博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【WPF】CommandParameter解决多传参问题
阅读量:6828 次
发布时间:2019-06-26

本文共 4074 字,大约阅读时间需要 13 分钟。

原文:

方法一:传参按钮控件自身绑定的ItemSource

用WAF框架实现MVVM,按钮的点击事件都要通过Command来传递到这个View对应的ViewModel上,再通过ViewModel传递到上层的Controller层,在Controller层通过DelegateCommand处理按钮真正的事件。有时候需要给该Command附加上一些参数(CommandParameter),但是默认CommandParameter只能传递一个参数。谷歌搜到的解决方法很复杂,于是想了个办法CommandParameter参数传递的是这个按钮控件自身绑定的ItemSource,然后通过从ItemSource身上的DataContext来拿到数据,再截取字符串分割得到想要的部分数据(或者强转为ItemSource对应的实体类)。

正常情况下,Button的绑定:

这个Command会沿着View –> ViewModle –> Controller层传递。

如果这个Button是ListBox的Item,这个ListBox的Item要使用数据模板,且ItemsSource绑定到了这组Button的数据源,是这样绑:

这个ItemSource绑定的DataList是ViewModle中的一个实例列表。ViewModel关键代码如下:

private ICommand refreshDesignCommand; // 向上传递这个Command:View-->ViewModel-->Controllerpublic ICommand RefreshDesignCommand{    get { return refreshDesignCommand; }    set { SetProperty(ref refreshDesignCommand, value); }}private ObservableCollection
dataList = null;public ObservableCollection
DataList{ get { return dataList; } set { dataList = value; }}

实体类:

public class GoodsJsonData{    public string id { get; set; }      // 还可用于图片被点击调时,标记出是哪个缩略图被点击    public string icon { get; set; }    // 缩略图    public string image { get; set; }   // 大图    public string model { get; set; }   // 该商品对应的模型XML    public override string ToString()    {        return "id = " + id + " , icon = " + icon + " , image = " + image + " , model = " + model;    }}

Controller层的关键代码:

private readonly DelegateCommand refreshDesignCommand;  // 缩略图的点击回调[ImportingConstructor]public WebImageController(){    this.refreshDesignCommand = new DelegateCommand(p => RefreshDesignCommand((Button)p));}private void RefreshDesignCommand(Button btn){    // 方法一:将DataContext打印字符串,截取出目标数据    string dataContext = btn.DataContext.ToString();    System.Console.WriteLine(dataContext);          // id = 000201 , icon = http://192.168.1.222/mjl/4-01.png , image = 2/造型/4-01.png , model = xml/qiang07.xml    // 截取字符串来获得目标数据。    // 方法二:将DataContext强转为ItemSource对应的实体类类型    GoodsJsonData data = (GoodsJsonData)btn.DataContext;    // do what you want !

坑点:

  • 如果这个DataList列表的内容需要同步刷新,则类型**必须是**ObservableCollection。否则就算控件与数据绑定成功,控件只在初始化时能够正确显示数据,之后数据发生改变时,控件不会自动刷新。
  • WPF可以传递控件自身绑定的ItemSource数据,通过ItemSource携带的DataContext内容,来代替CommandParameter多传参的蛋疼问题。

其他建议:

  • 想要在一个控件上传递多个参数,可以传递控件自身,用控件的Tag和Uid属性绑定上数据。

 

今天在StackOverflow看到一个关于解决Command和CommandParameter的工具:

以后可能会用到,先Mark。之后抽空看看。


 

方法二:多路绑定MultiBinding结合转换器Converter的使用

该方法是网上搜到的主流方式。

 


 

方法三:其他Trick

思路:用其他控件的属性来记录数据。传参时传递按钮控件自身,再通过按钮控件的视觉树布局找到找到绑定了其他数据的控件。

XAML:

Controller:

// 按钮点击触发的事件private void YourCommand(object p){    Button btn = (Button)p; // 传参传递的是控件自身    DependencyObject parent = VisualTreeHelper.GetParent(btn);    List
list = this.FindVisualChildren
(parent); string studentId = list[0].Tag.ToString(); string studentName = (int)(list[1].Tag); int studentAge = list[2].Tag.ToString(); // do something...}// 从视觉树找到目标控件的所有子控件private List
FindVisualChildren
(DependencyObject depObj) where T : DependencyObject{ List
list = new List
(); if (depObj != null) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { DependencyObject child = VisualTreeHelper.GetChild(depObj, i); if (child != null && child is T) { list.Add((T)child); } List
childItems = FindVisualChildren
(child); // 递归 if (childItems != null && childItems.Count() > 0) { foreach (var item in childItems) { list.Add(item); } } } } return list;}

小结:

  • 按钮的CommandParameter绑定了自身,将自身作为点击后触发的回调函数的参数传入。再用该按钮控件去找到其他控件或UI元素。
  • 使用了按钮的兄弟节点Grid的Tag属性来绑定目标数据,选择用Grid是因为我们只想用它来传参,而不需要看到它。因此用其他UI元素的Tag属性来传参,再设置Visibility="Collapse"也是可行的。
  • 同样选择用兄弟节点也不是必须的。也可以是父节点或子节点,只要能通过视觉树VisualTreeHelper找到就行。

 

转载地址:http://ewykl.baihongyu.com/

你可能感兴趣的文章
numpy初始化
查看>>
移植gdb到海思3716板子的方法【转】
查看>>
为什么一些机器学习模型需要对数据进行归一化?
查看>>
【Linux】echo命令
查看>>
MySQL主从1205报错【转】
查看>>
SpringBoot启动和停止脚步
查看>>
BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)
查看>>
LWIP_STM32_ENC28J60(转)
查看>>
Visual Studio 2019 preview中体验C# 8.0新语法
查看>>
Linux下进程通信之管道
查看>>
CentOS 7创建自定义KVM模板(现有KVM迁移到另外一台机)
查看>>
Python异常处理详解
查看>>
Nginx服务状态的监控
查看>>
JDBC-ODBC桥接方法连接Excel数据库的方法
查看>>
使用WCF的Trace与Message Log功能
查看>>
电子书下载:Beginning iPhone 4 Development: Exploring the iOS SDK
查看>>
Qt的元对象(Meta-Object)系统简介
查看>>
matlab练习程序(最大似然估计)
查看>>
Oracle 各种查询语句
查看>>
工厂方法模式与IoC/DI
查看>>