当前位置:   article > 正文

【WPF】CommandParameter无法多传参?传递控件自身的ItemSource数据_commandparameter 自身

commandparameter 自身

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

正常情况下,Button的绑定:

<Button Command="{Binding BtnCommand}" />
  • 1

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

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

<ListBox x:Name="listBox" ItemsSource="{Binding DataList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid x:Name="grid">
                <local:WaitingProgress/>
                <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.BtnCommand}"
                    CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}"> <!-- 传参是Button控件绑定的ItemsSource,即这里是DataList列表 -->
                    <Image Tag="{Binding id}" x:Name="img" Stretch="UniformToFill" Width="150" Height="150" webImg:ImageDecoder.Source="{Binding icon}">
                    </Image>
                </Button>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>

    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Name="wrapPanel" HorizontalAlignment="Stretch" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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

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

private ObservableCollection<GoodsJsonData> dataList = null;
public ObservableCollection<GoodsJsonData> DataList
{
    get { return dataList; }
    set { dataList = value; }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

实体类:

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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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 !
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

坑点:

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

2017.1.3补充:

今天在StackOverflow看到一个关于解决Command和CommandParameter的工具:
http://xcommand.codeplex.com/
以后可能会用到,先Mark。之后抽空看看。


埋怨一下,妈蛋WPF这玩意真的很笨重,不玩个几年根本溜不动,坑得一逼。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/613360
推荐阅读
相关标签
  

闽ICP备14008679号