【问题标题】:Which button is clicked DataTemplate WPF MVVM单击哪个按钮 DataTemplate WPF MVVM
【发布时间】:2016-09-14 11:04:10
【问题描述】:

我的问题是如何知道点击了哪个按钮。我的按钮绑定到 ObservableCollection 类型的属性,该属性包含 Item 类型的对象,当单击按钮时,我需要在 ViewModel 中使用该对象。任何想法如何知道单击了哪个按钮?我有几个想法,比如发送多个命令参数(1.SelectedItems from ListBox 2.The Object from the button)或在单击按钮后将按钮中的对象绑定到 ViewModel 中的另一个 Item 类型的属性以使用它.任何想法都会受到赞赏。

我有这个用于按钮的 DataTemplate

<DataTemplate x:Key="ButtonTemplate">
            <WrapPanel>
                <Button x:Name="OrderButton"
                        FontSize="10"
                        Height="80" Width="80"
                        Content="{Binding Name}"
                        Command="{Binding OrderCommand, 
                                          Source={StaticResource OrderViewModel}}"
                        CommandParameter="{Binding ElementName=ListBoxUserControl, Path=SelectedItems}">
                </Button>
            </WrapPanel>
</DataTemplate>

我的视图模型

public class OrderViewModel : ObservableCollection<Order>, INotifyPropertyChanged
{ 
   public CreateOrderCommand CreateOrderCommand { get; set; }
   public ObservableCollection<Item> Data { get; set; }

 public OrderViewModel()
    {
        this.CreateOrderCommand = new CreateOrderCommand(this);
        DataObservableCollection data= new DataObservableCollection();
        Data = data;
    }
}

我像这样填充我的按钮

<WrapPanel x:Name="OrderButtons">
            <ItemsControl   ItemTemplate="{StaticResource ButtonTemplate}"
                            ItemsSource="{Binding Data, Source={StaticResource OrderViewModel}}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal">
                        </WrapPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
    </WrapPanel>

【问题讨论】:

  • 请描述你的意图,而不是你试图解决它的方式,参考meta.stackexchange.com/questions/66377/what-is-the-xy-problem。在 MVVM 中,您不应该关心 ui 控件是什么。你的视图模型应该被设计成可以按照你的意愿处理事情。
  • 我想在我的 ViewModel 中使用 Button 的数据上下文,并从同一个 Button 的另一个控件发送 CommandParameter。

标签: c# wpf mvvm


【解决方案1】:

如果您希望按钮的数据上下文(即来自您的项目源的项目)作为命令参数,只需将 Button.CommandParameter 绑定更改为 CommandParamter="{Binding}",或者, CommandParameter="{Binding RelativeSource={RelativeSource Self}}" 如果您想要实际点击的按钮。

【讨论】:

  • 我知道如何发送 Button 数据上下文,但在这种情况下,如何将 ListBox 控件中的 Button 和 SelectedItems 的数据上下文作为参数发送?
【解决方案2】:

首先使用 CommandParameter 发送 Button DataContext。要发送 Listbox 的 SelectedItem,您可以使用

<Listbox SelectedItem="{Binding SelectedItem}"/> 

在您的列表框中,并在您的 ViewModel 中创建一个 SelectedItem 属性。

private YourItemObject mySelectedItem;
    public YourItemObject SelectedItem
    {
        get { return mySelectedItem; }

        set
        {
             value = mySelectedItem
        }

现在,当 Button 获得 clicket 时,您可以在 ViewModel 中使用 SelectedItem。如果您有多个选择,它会变得有点棘手;)。

private ButtonClicked(Parameter object)
{
   SelectedItem.UsingIt();
   if(object is YourButtonDataContext){
        YourButtonDataContext.UsingIt();
   }
}

使用多选更新:

使用多选,您必须创建自己的列表框。

public class CustomListBox : ListBox
{
    public CustomListBox()
    {
        this.SelectionChanged += CustomListBox_SelectionChanged;
    }

    void CustomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        this.SelectedItemsList = this.SelectedItems;
    }
    #region SelectedItemsList

    public IList SelectedItemsList
    {
        get { return (IList)GetValue(SelectedItemsListProperty); }
        set { SetValue(SelectedItemsListProperty, value); }
    }



    public static readonly DependencyProperty SelectedItemsListProperty =
            DependencyProperty.Register("SelectedItemsList", typeof(IList), typeof(CustomListBox), new PropertyMetadata(null));


    #endregion
}

在 ViewModel 中,您必须拥有一个带有 SelectedItems 的属性。

private IList mySelectedData = new List<SelectedDataObject>();
    public IList SelectedData
    {
        get { return mySelectedData ; }

        set
        {
            if (mySelectedData != value)
            {
                mySelectedData = value;
                RaisePropertyChanged(() => SelectedData);
            }
        }
    }

XAML 如下所示:

<local:CustomListBox ItemsSource="{Binding YourList}" SelectionMode="Extended" SelectedItemsList="{Binding SelectedData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    ...
</local:CustomListBox>

DataGrid 中多选的来源是:https://stackoverflow.com/a/22908694/3330227

【讨论】:

  • 我确实这样做了,但我有多个选择。你能帮我解决一下吗?
  • 更新它。我已经用 Datagrid 完成了它。我希望它与列表框相同。
  • 我很快使用了这篇文章grokys.blogspot.bg/2010/07/… 并设法使我的程序工作,但是当列表框在模板中时,它会选择每个列表框中的每个项目。我会检查您的答案并尝试实施它。当我完成后,我会选择一个答案。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 2013-08-09
  • 2014-04-24
  • 2011-10-21
  • 2017-07-24
  • 1970-01-01
  • 2017-10-05
相关资源
最近更新 更多