ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

WPF MVVM事件绑定

2022-01-09 14:00:58  阅读:190  来源: 互联网

标签:DelegateCommand string MVVM 绑定 private WPF public Textbox


事件转命令

在我们大多数拥有Command依赖属性的控件,大多数是由于继承了ICommandSource接口,ICommandSource接口拥有三个函数成员,ICommand接口类型属性Command,object 类型属性CommandParameter,IInputElement 类型属性CommandTarget,而基本继承着ICommandSource接口这两个基础类的就是ButtonBase和MenuItem,因此像Button,Checkbox,RadioButton等继承自ButtonBase拥有着Command依赖属性,而MenuItem也同理。但是我们常用的Textbox那些就没有。

现在我们有这种需求,我们要在这个界面基础上新增第二个Textbox,当Textbox的文本变化时,需要将按钮的Name和第二个Textbox的文本字符串合并更新到第一个Textbox上,我们第一直觉肯定会想到用Textbox的TextChanged事件,那么如何将TextChanged转为命令?

首先我们在xmal界面引入:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

该程序集 System.Windows.Interactivity dll是在 Expression Blend SDK中的,而Prism的包也也将其引入包含在内了,因此我们可以直接引入,然后我们新增第二个Textbox的代码:

 <Grid>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="12,44,0,0" TextWrapping="Wrap" Text="{Binding CurrentTime2,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="TextChanged">
                    <i:InvokeCommandAction Command="{Binding DelegateCommand1}" CommandParameter="{Binding ElementName=mybtn}"></i:InvokeCommandAction>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding CurrentTime}" VerticalAlignment="Top" Width="125"/>
        <Button Content="Button" Command="{Binding DelegateCommand}" Name="mybtn" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}}" HorizontalAlignment="Left" Margin="11,75,0,0" VerticalAlignment="Top" Width="75"/>
        <CheckBox Content="CheckBox" IsChecked="{Binding Ischecked}" HorizontalAlignment="Left" Margin="91,79,0,0" VerticalAlignment="Top"/>

    </Grid>

 后台代码

public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        private string _currentTime;

        public string CurrentTime
        {
            get { return _currentTime; }
            set { SetProperty(ref _currentTime, value); }
        }
        private bool _ischecked;

        public bool Ischecked
        {
            get { return _ischecked; }
            set { SetProperty(ref _ischecked, value); }
        }
        private string _currentTime2;

        public string CurrentTime2
        {
            get { return _currentTime2; }
            set { SetProperty(ref _currentTime2, value); }
        }
        private DelegateCommand<object> delegateCommand1;
        public DelegateCommand<object> DelegateCommand1 =>delegateCommand1 ?? (delegateCommand1 = new DelegateCommand<object>(ShowText));
        private DelegateCommand<object> delegateCommand;
        public DelegateCommand<object> DelegateCommand => delegateCommand ?? (delegateCommand = new DelegateCommand<object>(ShowButton).ObservesCanExecute(()=>Ischecked));
        private void ShowButton(object obj)
        {
            this.CurrentTime = ((Button)obj).Name + DateTime.Now.ToString();
        }
        private void ShowText(object obj)
        {
            this.CurrentTime = CurrentTime2+((Button)obj).Name + DateTime.Now.ToString();
        }
        public MainWindowViewModel()
        {

        }
    }

 上面我们在xaml代码就是添加了对TextBox的TextChanged事件的Blend EventTrigger的侦听,每当触发该事件,InvokeCommandAction就会去调用TextChangedCommand命令

将EventArgs参数传递给命令

上面介绍的事件绑定并不足以应对所有情况,因为很多情况下我们还要从事件的EventArgs中获取数据,例如从MouseMove事件参数中获取鼠标位置和按键状态等,但InvokeCommandAction在未对CommandParameter绑定的情况下给Execute方法传递的参数为null。因此我们需要自己写一个类来处理事件到命令的绑定。

 

看一下上面我们用到的InvokeCommandAction,继承自TriggerAction<DependencyObject>,TriggerAction是一个抽象类,我们只要继承这个类并实现Invoke方法即可。TriggerAction在MSDN中的介绍如下:

TriggerAction 类 (System.Windows.Interactivity) | Microsoft Docs

我简单实现了以下,代码如下图所示,其中依赖项属性是借助propdp代码段生成的,要不实在记不住,输入那么多代码也好麻烦。使用的时候用来代替之前的InvokeCommandAction,不绑定CommandParameter则传递的就是事件的参数。如果绑定了CommandParameter,那么传递的就是绑定的参数。

事件绑定的示例

<esri:MapView x:Name="MyMap" Style="{DynamicResource MapViewStyle}"  Map="{Binding Map, Source={StaticResource MapViewModel}}" >
             <i:Interaction.Triggers>
                <i:EventTrigger EventName="GeoViewTapped">
                    <commands:MyEventCommand Command="{Binding GetmapTappedCommand,Source={StaticResource MapViewModel}}" >
                        
                    </commands:MyEventCommand>
                    <!--<i:InvokeCommandAction >
                    </i:InvokeCommandAction>-->
                </i:EventTrigger>
                <i:EventTrigger EventName="GeoViewTapped" >
                    <i:InvokeCommandAction  Command="{Binding GetmapTappedCommande,Source={StaticResource MapViewModel}}" CommandParameter="{Binding ElementName=MyMap }">
                    </i:InvokeCommandAction>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </esri:MapView>
   private DelegateCommand<GeoViewInputEventArgs> _getmapTapped;
        public DelegateCommand<GeoViewInputEventArgs> GetmapTappedCommand =>
            _getmapTapped ?? (_getmapTapped = new DelegateCommand<GeoViewInputEventArgs>(ExecuteGetCurrentTimeCommand));

 

标签:DelegateCommand,string,MVVM,绑定,private,WPF,public,Textbox
来源: https://blog.csdn.net/qq_40098572/article/details/122390456

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有