WPF Prism框架-右键在位编辑 ListView

右键菜单关联viewModel 命令

 在位编辑ListItem

Prism框架 MVVM 页面右键快捷菜单绑定 绑定 ViewModel方法。

0.引用库

  <ItemGroup>
    <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
    <PackageReference Include="Prism.DryIoc" Version="8.1.97" />
  </ItemGroup>

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True">
    
    <Grid>
        <StackPanel>
            <ContentControl prism:RegionManager.RegionName="ContentRegion" />
            <ContentControl prism:RegionManager.RegionName="ContentRegionB" />
        </StackPanel>       
    </Grid>    
   
</Window>

MainWindow.xaml.cs

using Prism.Ioc;
using Prism.Regions;
using System.Windows;

namespace WpfApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        IContainerExtension _container;
        IRegionManager _regionManager;

        public MainWindow(IContainerExtension container, IRegionManager regionManager)
        {
            InitializeComponent();
            _container = container;
            _regionManager = regionManager;
            regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.ViewA));
            regionManager.RegisterViewWithRegion("ContentRegionB", typeof(Views.ViewB));

        }

    }
}

1. ViewA 视图

<UserControl x:Class="WpfApp.Views.ViewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <StackPanel>
            <TextBlock>ViewA</TextBlock>
            <TextBlock Text="{Binding Title}"/>
            <ListView ItemsSource="{Binding Items}">
                <ListView.ContextMenu>
                    <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"  x:Name="listView">
                        <MenuItem Header="New" Command="{Binding NewCommand}"/>
                        <MenuItem Header="Edit" Command="{Binding EditCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                        <MenuItem Header="Delete" Command="{Binding DeleteCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                    </ContextMenu>
                </ListView.ContextMenu>
            </ListView>
        </StackPanel>        
        
    </Grid>
</UserControl>

2. ViewA 模型

using Prism.Commands;
using Prism.Mvvm;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;

namespace WpfApp.ViewModels;

public class ViewAViewModel : BindableBase
{
    private string _title = "Hello, Prism!";
    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }

    private ObservableCollection<string> _items;
    public ObservableCollection<string> Items
    {
        get { return _items; }
        set { SetProperty(ref _items, value); }
    }

    public ICommand NewCommand { get; private set; }
    public ICommand EditCommand { get; private set; }
    public ICommand DeleteCommand { get; private set; }

    public ViewAViewModel()
    {
        Items = new ObservableCollection<string> { "Item 1", "Item 2", "Item 3" };

        NewCommand = new DelegateCommand(OnNew);
        EditCommand = new DelegateCommand<string>(OnEdit);
        DeleteCommand = new DelegateCommand<string>(OnDelete);
    }

    private void OnNew()
    {
        MessageBox.Show("new");

    }

    private void OnEdit(string item)
    {
        if (item == null)
        {
            // 处理空值的情况,例如记录日志或提示用户
            Console.WriteLine("Selected item is null. Cannot edit.");
            return;
        }

        MessageBox.Show($"Editing item: {item}");
        // 编辑逻辑
        Console.WriteLine($"Editing item: {item}");
    }

    private void OnDelete(string item)
    {
        if (item == null)
        {
            MessageBox.Show("Selected item is null. Cannot delete.");

            // 处理空值的情况,例如记录日志或提示用户
            Console.WriteLine("Selected item is null. Cannot delete.");
            return;
        }

        if (Items.Contains(item))
        {
            MessageBox.Show($"Item '{item}' remove the collection.");

            Items.Remove(item);
        }
        else
        {
            // 处理项目不在集合中的情况,例如记录日志或提示用户

            MessageBox.Show($"Item '{item}' not found in the collection.");
            Console.WriteLine($"Item '{item}' not found in the collection.");
        }
    }

}

  viewA视图关键参数

   ContextMenu 与viewA 的 DataContext绑定。

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"  x:Name="listView">
      <MenuItem Header="New" Command="{Binding NewCommand}"/>
      <MenuItem Header="Edit" Command="{Binding EditCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
       <MenuItem Header="Delete" Command="{Binding DeleteCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>

3. ViewB 视图 

ViewB.xaml

<UserControl x:Class="WpfApp.Views.ViewB"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp.Views"           
             xmlns:e="clr-namespace:WpfApp"
             mc:Ignorable="d" 
             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
             d:DesignHeight="450" d:DesignWidth="800">

    <UserControl.Resources>
        <e:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        <e:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
        <DataTemplate x:Key="ItemTemplate">
            <Grid>
                <TextBlock Text="{Binding Text}" Visibility="{Binding IsEditing, Converter={StaticResource InverseBooleanToVisibilityConverter}}" VerticalAlignment="Center"/>
                <TextBox Text="{Binding Text, Mode=TwoWay}" 
                         Visibility="{Binding IsEditing, Converter={StaticResource BooleanToVisibilityConverter}}"
                         VerticalAlignment="Center">
                    
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="LostFocus">
                            <i:InvokeCommandAction Command="{Binding ConfirmEditCommand}"/>
                        </i:EventTrigger>                      


                        <i:EventTrigger EventName="KeyDown">
                            <e:KeyDownCommandAction Command="{Binding ConfirmEditCommand}" Key="Enter"/>
                        </i:EventTrigger>
                        
                    </i:Interaction.Triggers>
                </TextBox>
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

    <Grid>
        <StackPanel>       
            <ListView ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemTemplate}" x:Name="listView">
                <ListView.ContextMenu>  
                    <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
                        <MenuItem Header="Edit"
                                  Command="{Binding PlacementTarget.SelectedItem.EditCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                                   CommandParameter="{Binding PlacementTarget.SelectedItem,   RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                    </ContextMenu>
                </ListView.ContextMenu>
            </ListView>
        </StackPanel>
    </Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfApp.ViewModels;

namespace WpfApp.Views
{
    /// <summary>
    /// ViewB.xaml 的交互逻辑
    /// </summary>
    public partial class ViewB : UserControl
    {
        public ViewB()
        {
            InitializeComponent();
            //DataContext = new ViewBViewModel();
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            var textBox = sender as TextBox;
            if (textBox != null)
            {
                var itemViewModel = textBox.DataContext as ItemViewModel;
                if (itemViewModel != null && itemViewModel.ConfirmEditCommand.CanExecute(null))
                {
                    itemViewModel.ConfirmEditCommand.Execute(null);
                }
            }
        }
    }
}

4.ViewB 模型

ViewBViewModel.cs

using Prism.Commands;
using Prism.Mvvm;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace WpfApp.ViewModels;
public class ItemViewModel : BindableBase
{
    private string _text;
    public string Text
    {
        get { return _text; }
        set { SetProperty(ref _text, value); }
    }

    private bool _isEditing;
    public bool IsEditing
    {
        get { return _isEditing; }
        set { SetProperty(ref _isEditing, value); }
    }

    public ICommand EditCommand { get; }
    public ICommand ConfirmEditCommand { get; }
    public ICommand CancelEditCommand { get; }

    public ItemViewModel()
    {
        EditCommand = new DelegateCommand(OnEdit);
        ConfirmEditCommand = new DelegateCommand(OnConfirmEdit);
        CancelEditCommand = new DelegateCommand(OnCancelEdit);
    }

    private void OnEdit()
    {
        //  MessageBox.Show("OnEdit");
        IsEditing = true;
    }

    private void OnConfirmEdit()
    {
        IsEditing = false;
    }

    private void OnCancelEdit()
    {
        IsEditing = false;
    }
}

public class ViewBViewModel : BindableBase
{
    private ObservableCollection<ItemViewModel> _items;
    public ObservableCollection<ItemViewModel> Items
    {
        get { return _items; }
        set { SetProperty(ref _items, value); }
    }

    public ViewBViewModel()
    {
        Items = new ObservableCollection<ItemViewModel>
        {
            new ItemViewModel { Text = "Item 4" },
            new ItemViewModel { Text = "Item 5" },
            new ItemViewModel { Text = "Item 6" }
        };
    }
}

5. 转换类

BooleanToVisibilityConverter.cs

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WpfApp;

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool boolean)
        {
            return boolean ? Visibility.Visible : Visibility.Collapsed;
        }
        return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility visibility)
        {
            return visibility == Visibility.Visible;
        }
        return false;
    }
}

public class InverseBooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool boolean)
        {
            return boolean ? Visibility.Collapsed : Visibility.Visible;
        }
        return Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility visibility)
        {
            return visibility != Visibility.Visible;
        }
        return true;
    }
}

6. 按键类

KeyDownCommandAction.cs

using Microsoft.Xaml.Behaviors;
using System.Windows;
using System.Windows.Input;

namespace WpfApp;
public class KeyDownCommandAction : TriggerAction<UIElement>
{
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(KeyDownCommandAction), new PropertyMetadata(null));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public Key Key { get; set; }

    protected override void Invoke(object parameter)
    {
        var keyEventArgs = parameter as KeyEventArgs;
        if (keyEventArgs != null && keyEventArgs.Key == Key)
        {
            if (Command != null && Command.CanExecute(null))
            {
                Command.Execute(null);
            }
        }
    }
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF Prism框架是一个基于WPF的应用程序开发框架,它提供了一组通用的开发模式和最佳实践,帮助开发人员构建模块化、可扩展、可重用、可测试和易于维护的复杂客户端应用程序。该框架的目标是帮助开发人员通过使用模块化开发、依赖注入和事件聚合等技术,优化应用程序的架构,提高应用程序的质量和可维护性。 WPF Prism框架的主要功能包括: 1. 模块化开发:WPF Prism框架允许开发人员将应用程序拆分成多个模块,每个模块都可以独立开发和测试,然后再将这些模块组合成一个完整的应用程序。 2. 依赖注入:WPF Prism框架使用依赖注入技术,使得应用程序中的各个模块之间的耦合度降低,提高了代码的可重用性和可测试性。 3. 事件聚合:WPF Prism框架提供了一个事件聚合器,可以让应用程序中的不同模块之间通过事件进行通信,从而解耦不同模块之间的关系。 4. 命令:WPF Prism框架提供了一个命令系统,可以帮助开发人员将应用程序中的业务逻辑与用户界面分离,提高代码的可重用性和可测试性。 5. 状态管理:WPF Prism框架提供了一个状态管理系统,可以帮助开发人员管理应用程序中的状态信息,从而提高应用程序的可维护性。 总之,WPF Prism框架提供了一种优秀的方式来设计和构建WPF应用程序,使得开发人员可以更加专注于应用程序的业务逻辑,而不必担心应用程序的架构和细节问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值