• WPF自定义命令


    自定义命令,可以分为两个层次来理解

    1.声明自己的RoutedCommand实例,这个层次比较浅

    2.从实现ICommand接口开始,这个才算的上真正的自定义命令

    自定义命令的目的是为了把业务逻辑转移到命令内部,而不是需要捕捉到命令之后再回过头去处理。

    要想自定义命令,就不能不了解命令系统的几个要素:

    1.命令(Command):WPF的命令实际上就是实现了ICommand接口的类,平时使用最多的就是RoutedCommand类.

    2.命令源(Command Source):命令的发送者,是实现了ICommandSource的类,平时用的Button就实现了这个接口

    3.命令目标(Command Target):即命令将发送给谁,或者说命令的作用对象,是实现了IINputElement的类

    4.命令关联(Command Binding):负责把一些外围逻辑与命令关联起来,比如执行之前对命令是否可以执行进行判断,命令执行之后还有那些后续工作

    了解了命令系统的几个要素,就可以自己定义命令了

    1.定义接口

    为了规范我们的命令源,更统一的通过命令来调用,我们约定一个接口,所有使用该命令的命令源必须是实现了该接口的类型。

    View Code
    interface IView
        {
            //是否更改
            bool IsChanged { get; set; }
    
            //方法
            void SetBinding();
            void Refresh();
            void Clear();
            void Save();
        }

    2.定义命令

    创建一个专门用于处理IView接口派生类的命令。我们说,命令就是实现了ICommand接口的类,接口包含两个方法,一个委托事件,我们这里只实现Excute方法

    View Code
    class ClearCommand:ICommand
        {
    
            public bool CanExecute(object parameter)
            {
                throw new NotImplementedException();
            }
    
            public event EventHandler CanExecuteChanged;
    
            public void Execute(object parameter)
            {
                IView view = parameter as IView;
                //这里体现了我们的业务逻辑
                view.Clear();
            }
        }

    3.定义命令源

    有了命令,下一步定义发送命令的命令源

    View Code
    class MyCommandSource:UserControl,ICommandSource
        {
            //命令
            public ICommand Command{ get;set; }
            //参数
            public object CommandParameter { get; set; }
            //目标
            public System.Windows.IInputElement CommandTarget { get; set; }
    
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                base.OnMouseLeftButtonDown(e);
    
                //执行命令
                if (this.Command != null)
                {
                    //目标作为参数
                    Command.Execute(this.CommandTarget);
                }
            }
        }

    4.定义命令的目标

    命令目标有两个限制,一个是实现IInputElement,另一个是我们定义的,要求实现接口IView

    分为两部分 一部分是XAML

    View Code
    <UserControl x:Class="CommandTest2.MiniView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Height="120" Width="200">
        <Grid>
            <Border CornerRadius="5" BorderBrush="LawnGreen" BorderThickness="2">
                <StackPanel>
                    <TextBox x:Name="txt1" Margin="5"></TextBox>
                    <TextBox x:Name="txt2" Margin="5"></TextBox>
                    <TextBox x:Name="txt3" Margin="5"></TextBox>
                    <TextBox x:Name="txt4" Margin="5"></TextBox>
                </StackPanel>
            </Border>
        </Grid>
    </UserControl>

    另一部分是后台代码

    View Code
    namespace CommandTest2
    {
        /// <summary>
        /// MiniView.xaml 的交互逻辑
        /// </summary>
        public partial class MiniView : UserControl,IView
        {
            public MiniView()
            {
                InitializeComponent();
            }
    
            public bool IsChanged
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public void SetBinding()
            {
                throw new NotImplementedException();
            }
    
            public void Refresh()
            {
                throw new NotImplementedException();
            }
    
            public void Save()
            {
                throw new NotImplementedException();
            }
    
            public void Clear()
            {
                txt1.Clear();
                txt2.Clear();
                txt3.Clear();
                txt4.Clear();
            }
        }
    }

    这样,我们需要的几个部分凑齐,就可以使用了

    窗体代码

    View Code
    <Window x:Class="CommandTest2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:CommandTest2"
            Title="Command" Height="205" Width="250">
        <StackPanel>
            <local:MyCommandSource x:Name="ctrlClear" Margin="10">
                <TextBlock Text="清除" FontSize="16" TextAlignment="Center"
                           Background="LightGreen" Width="80"></TextBlock>
            </local:MyCommandSource> 
            <local:MiniView x:Name="miniView"></local:MiniView>
        </StackPanel>
    </Window>

    后台调用也很简单

    View Code
    ClearCommand clrCommand = new ClearCommand();
                
    ctrlClear.Command = clrCommand;
    ctrlClear.CommandTarget = miniView;

    参考《深入浅出WPF》刘铁猛 第9章

    ps.工作需要,开始学习WPF,感觉跟ASP.NET还是有很多不一样的,在这里记录一下学习的历程,以便今后回顾之用,看如何一步步走的,走向何方

  • 相关阅读:
    js动态获取地址栏后的参数
    html页面保存数的两种方式
    微信开发之八 页面获取周围beacon设备
    【摄影】田子坊
    最好的时光在路上,最美的风景在远方
    【前端统计图】echarts实现简单柱状图
    js实现计时功能
    luogu 电车
    cogs luogu 砍树
    cogs 通往奥格瑞玛的道路 WD
  • 原文地址:https://www.cnblogs.com/goldren/p/2806912.html
Copyright © 2020-2023  润新知