简体   繁体   English

使用父级的DataContext(WPF - 动态菜单命令绑定)

[英]Using the parent's DataContext (WPF - Dynamic Menu Command Binding)

I looked over this web and google and the solutions didn't work for me. 我查看了这个网站和谷歌,解决方案对我不起作用。

I have a command on the ViewModel of a UserControl. 我在UserControl的ViewModel上有一个命令。 Well, The usercontrol have a ItemsControl binded to a ObservableCollection. 好吧,usercontrol有一个绑定到ObservableCollection的ItemsControl。 Inside the DataTemplate of the ItemsControl.ItemTemplate I have a button and I want to use the command. 在ItemsControl.ItemTemplate的DataTemplate中,我有一个按钮,我想使用该命令。 I can't bind the command because inside the DataTemplate, the datacontext is not the ViewModel but an item of the ObservableCollection. 我无法绑定命令,因为在DataTemplate中,datacontext不是ViewModel而是ObservableCollection的项。

The question is: How can I bind the button to the command if a lost the parent datacontext? 问题是:如果丢失了父datacontext,如何将按钮绑定到命令?

I think that this need to have an easy solution because I think that this is a common problem. 我认为这需要一个简单的解决方案,因为我认为这是一个常见的问题。

Imagine this sceneario: 想象一下这个场景:

You have a ListBox item with an observableCollection as the ItemsSource, so you are using a datatemplate inside the ListBox for every element in the collection. 您有一个带有observableCollection的ListBox项作为ItemsSource,因此您在ListBox中为集合中的每个元素使用了一个datatemplate。 Well, you want to delete the selected item and you put a button in every row for that job. 好吧,您想删除所选项目,并在该行的每一行中放置一个按钮。 ¿How do you do that? 你是怎样做的?

In MVP, I can do this in the click event of the button: 在MVP中,我可以在按钮的单击事件中执行此操作:

Button but = e.Source as Button;

if (but != null)
      Presenter.ActualNote = but.DataContext as Note;

In short. 简而言之。 You send the datacontext of the row (the selected item) to the presenter. 您将行的datacontext(所选项目)发送到演示者。

But, how can I do it in the mvvm way? 但是,我怎么能用mvvm方式呢? Because I need to use a command but I can't assign the command to the button because the button does know nothing about the ViewModel (where the command exists). 因为我需要使用命令但是我无法将命令分配给按钮,因为该按钮对ViewModel(命令所在的位置)一无所知。

As you can see, the button has to exist inside the datatemplate, then the datacontext is not the ViewModel anymore.... There is why I need to access to the parent's DataContext, for access to the command. 正如您所看到的,按钮必须存在于datatemplate中,然后datacontext不再是ViewModel ....这就是我需要访问父级DataContext以访问命令的原因。

I hope that you understand my problem better. 我希望你能更好地理解我的问题。

Thank you. 谢谢。

Use the binding below for your button's command: 使用下面的绑定作为按钮的命令:

{Binding DataContext.CommandName, 
         RelativeSource={RelativeSource FindAncestor, 
                         AncestorType={x:Type MyUserControl}}}

This will tell it to find your UserControl and use its DataContext. 这将告诉它找到你的UserControl并使用它的DataContext。

If you want a dirty, MVVM-breaking solution, then set the Tag="{Binding}" on the button and handle the Click event. 如果你想要一个破坏性的MVVM解决方案,那么在按钮上设置Tag =“{Binding}”并处理Click事件。 In the event handler, call the command on your ViewModel. 在事件处理程序中,在ViewModel上调用该命令。

Ok, then what about modifying your data item class so that it has a property referencing to the whole model view? 那么,那么修改数据项类以使其具有引用整个模型视图的属性呢?

If your ItemsSource is of type ObservableCollection<DataItem> then modify DataItem type like this: 如果您的ItemsSource的类型为ObservableCollection<DataItem>则修改DataItem类型,如下所示:

public class DataItem
{
    public BusinessObject Value { get; set; }

    private ModelView modelView;

    public ModelView ModelView
    {
        get
        {
            return modelView;
        }
    }

    public DataItem(ModelView modelView)
    {
        this.modelView = modelView;
    }
}

RelativeSource works, but I don't think it's right to let controls to prowl across each other's properties. RelativeSource有效,但我不认为让控件在彼此的属性中徘徊是正确的。 It is strange that button placed inside an item view does something with an outer data source rather than with the bound item. 奇怪的是,放置在项目视图中的按钮使用外部数据源而不是绑定项目执行某些操作。 You might need to review the program code's design. 您可能需要查看程序代码的设计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM