(六)WPF数据驱动模式

 WPF开发方式; MVVM(Model View ViewModel)
1.绑定XAML数据方式
    在 XAML中添加绑定数据和绑定的操作属性
        Content="{Binding MyVar}"

  在XAML对应了的窗体类的构造函数添加数据绑定
        this.DataContext = mainViewModel; //让此页面的数据取MainViewModel对象里去寻找

 

2.实现INotifyPropertyChanged接口更新XAML数据
    因为只在构造函数添加了数据绑定,如果在后续数据变动时则无法更新数据,所以要在MainViewMoel业务逻辑(已经包含数据模型了)中实现INotifyPropertyChanged接口,然后通过委托类型的事件更新绑定字段的数据:

 3.建立CommandBase实现ICommand接口执行按钮动作方法
     建立一个类CommandBase实现ICommand接口:按钮 Command="{Binding ValueCommand}" 行为绑定ValueCommand字段

    class CommandBase : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            //绑定的这个命令的按钮是否可用
            return DoCanExecute?.Invoke(parameter) == true;//这里面没有任何执行逻辑,逻辑都被委托Func丢出去了,实例化时传进来含返回值的方法即可
        }

        public void Execute(object parameter)//parameter是订阅此此接口方法的按钮传递过来的参数
        {
        
            DoAction?.Invoke(parameter);//在应用程序主线程上执行指定委托?是Require的缩写?
            
        }

        public Action<object> DoAction { get; set; }//定义一个Action<object> 委托类型,委托需要Invoke()执行
        //那么这个委托在创建CommandBase对象时就可以传递进来一个自定义方法执行了
        //此类是非静态的,所以所有Control都可以使用
        public Func<object, bool> DoCanExecute { get;set; }//定义有返回值的委托类型Func
    }

 

  在实现三个方法同时,自定义一个无返回值的Action委托类型(有返回值的则是Func<>)DoAction,Action<T1,T2,...>参数和传递进来的方法参数对应,属性为空,类为非静态,所以在创建CommandBase对象时就可以通过委托传递进来一个方法。
在业务逻辑类MainViewModel定义ICommand类型字段,在字段封装属性同时创建CommandBase对象,并创建类内DoAction委托将方法传进去给Execute()方法执行,Execute会在绑定ValueCommand字段按钮动作时执行。

  public class MainViewModel:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string myVar="AA";
        private Brush _valueColor=Brushes.Orange;

        public Brush ValueColor
        {
            get { return _valueColor; }
            set { _valueColor = value; }
        }

        public string MyVar
        {
            get { return myVar; }
            set { myVar = value;
                PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("MyVar"));//更新绑定此属性的控件

            }
        }


        //行为绑定处理

        private ICommand _valueCommand;//定义接口类型的字段,
        //通过按钮Command属性绑定行为,按钮点击则会触发实现接口类CommandBase中的Execute()方法
        //通过属性CommandParameter="123"传递参数

        public ICommand ValueCommand
        {
            get {
                if (_valueCommand == null)
                {
                    _valueCommand = new CommandBase() { DoAction = new Action<object>(ValueCommandAction),
                                                       DoCanExecute=new Func<object, bool>(CanExcute) };//实例化同时传递方法给委托DoAction在CommandBase中执行,父类引用指向子类对象
                  
                }
                return _valueCommand;
                }
            set { _valueCommand = value; }
        }

        private void ValueCommandAction(object obj)
        {
            MessageBox.Show("Test");
        }

        private bool CanExcute(object obj)
        {
            return !string.IsNullOrEmpty(MyVar);//判断是否为空
        }
    }

 

posted @ 2024-10-02 13:03  灰色小五  阅读(107)  评论(0)    收藏  举报