c# - WPF 命令绑定(bind)到带有 MVVM 的 DataItemTemplate

标签 c# wpf mvvm datatemplate commandbinding

我正在开发一个 WPF 项目,并且正在尝试遵循 MVVM 模式。过去我只使用 DataTemplates 来显示信息,但现在我想在我的模板上放置一个按钮,该按钮执行与包含单击按钮的项目相关的操作。我试图找出将我的代码绑定(bind)到我的按钮的最佳方法,以使代码知道单击了哪个按钮。

我的 WindowViewModel包含通过命令属性公开的中继命令,以及 ObservableCollection的“项目”。

public class WindowViewModel
{
    public ICommand ChangeItemCommand { get; private set; }

    public ObservableCollection<Item> Items {get;private set;}

    public WindowViewModel()
    {
        ChangeItemCommand = new RelayCommand(new Action<object>(this.ChangeItem));
        Items = new ObservableCollection<Item>();
    }

    public void ChangeItem(object o)
    {
        string key = (string)o;
        //do something to the item with provided key
    }
}

我的 ItemViewModel包含 ItemKey属性来识别项目。
public class ItemViewModel
{
    public string ItemName { get; private set; }
    public string ItemKey { get; private set; }
}

我的列表框 DataTemplate 看起来像这样。
<DataTemplate DataType="local:ItemViewModel">
    <StackPanel Orientation="Horizontal">
        <Label Content="{Binding ItemName}"/>
            <Button Command="???" CommandParameter="{Binding ItemKey}"/>
         </StackPanel>
</DataTemplate>

所以我试图找出将按钮命令绑定(bind)到 WindowViewModel.ChangeItemCommand 的最佳方法。的WindowViewModel .

我正在考虑的一种选择是将命令属性添加到 ItemViewModelWindowViewModel 创建实例时设置
public class ItemViewModel
{
    public string ItemName { get; private set; }
    public string ItemKey { get; private set; }
    public ICommand ChangeItemCommand{ get; private set; }
}

<Button Command="{Binding ChangeItemCommand}" CommandParameter="{Binding ItemKey}"/>

或者,我可以直接绑定(bind)到 WindowViewModel.ChangeItemCommand使用 RelativeSource 的属性.
<Button 
   Command="{Binding Path=ChangeItemCommand, 
                     RelativeSource={RelativeSource AncestorType={x:Type MyAppAWindow}}}" 
   CommandParameter="{Binding ItemKey}"/>

注意:我不完全确定我做对了

那么推荐哪个,或者有其他更好的方法吗?

最佳答案

这两个选项都很好,但真正要做出的决定是谁应该是这个 Action 的所有者,在 MVVM 中应该首先设计 View 模型,然后 View 应该正确使用它们。

例如

  • 如果这个 Action 是说 RemoveItem 那么我会说它属于 WindowViewModel (因为这是关于更改 WindowViewModel 公开的集合)。
  • 但是说这个 Action 是RefreshItemDataChangeItemDetails (例如 ItemNameItemStatus )那么它属于 ItemViewModel (因为这个 ItemViewModel 可以在支持此操作的其他窗口中使用)

  • 因此,我建议您首先考虑功能、可重用性等来设计 ViewModel,然后使用合适的绑定(bind)功能(即 RelativeSourceElementName、直接等)。

    关于c# - WPF 命令绑定(bind)到带有 MVVM 的 DataItemTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20693657/

    相关文章:

    design-patterns - 在MVVM模型层次结构中共享值(value)

    c# - 知道只有一个表单实例,在表单中使用静态属性是否是一种不好的做法?

    c# - 不同命名空间中的类

    c# - 单击按钮时在表单之间传递变量

    wpf - 如何将Textbox的内容保存到文本文件中

    c# - 使用 WPF/C# 中的绑定(bind)获取更改的数据

    c# - 如何使用 DataContractSerializer 反序列化文件中的 WCF soap 响应消息?

    c# - 我如何摆脱 Datagrid 创建的额外行

    c# - .NET 5 中的 Windows API - Microsoft.Windows.SDK.NET.dll 是 25MB?

    wpf - LayoutTransform 自定义样式 wpf