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

发布于 2024-07-24 17:58:15 字数 937 浏览 2 评论 0原文

我查看了这个网络和谷歌,这些解决方案对我不起作用。

我在 UserControl 的 ViewModel 上有一个命令。 好吧,用户控件有一个绑定到 ObservableCollection 的 ItemsControl。 在 ItemsControl.ItemTemplate 的 DataTemplate 内,我有一个按钮,我想使用该命令。 我无法绑定该命令,因为在 DataTemplate 内部,数据上下文不是 ViewModel,而是 ObservableCollection 的一项。

问题是:如果丢失了父数据上下文,如何将按钮绑定到命令?

我认为这需要一个简单的解决方案,因为我认为这是一个常见问题。

想象一下这个场景:

您有一个 ListBox 项目,其中一个 observableCollection 作为 ItemsSource,因此您在 ListBox 内为集合中的每个元素使用一个数据模板。 好吧,您想要删除所选项目,并在该作业的每一行中放置一个按钮。 你是怎样做的?

在 MVP 中,我可以在按钮的单击事件中执行此操作:

Button but = e.Source as Button;

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

简而言之。 您将行(所选项目)的数据上下文发送给演示者。

但是,我该如何以 mvvm 方式做到这一点呢? 因为我需要使用命令,但无法将该命令分配给按钮,因为按钮对 ViewModel(命令所在的位置)一无所知。

正如您所看到的,按钮必须存在于数据模板内,然后数据上下文就不再是 ViewModel...这就是为什么我需要访问父级的 DataContext 才能访问命令。

我希望你能更好地理解我的问题。

谢谢。

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. Well, The usercontrol have a ItemsControl binded to a ObservableCollection. Inside the DataTemplate of the ItemsControl.ItemTemplate I have a button and I want to use the command. I can't bind the command because inside the DataTemplate, the datacontext is not the ViewModel but an item of the ObservableCollection.

The question is: How can I bind the button to the command if a lost the parent 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. 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:

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.

But, how can I do it in the mvvm way? 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).

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.

I hope that you understand my problem better.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

佼人 2024-07-31 17:58:16

好的,那么如何修改数据项类,使其具有引用整个模型视图的属性呢?

如果您的 ItemsSource 类型为 ObservableCollection ,则修改 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;
    }
}

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:

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

    private ModelView modelView;

    public ModelView ModelView
    {
        get
        {
            return modelView;
        }
    }

    public DataItem(ModelView modelView)
    {
        this.modelView = modelView;
    }
}
你是暖光i 2024-07-31 17:58:16

relativeSource 可以工作,但我认为让控件在彼此的属性之间徘徊是不对的。 奇怪的是,放置在项目视图内的按钮对外部数据源而不是绑定项目执行某些操作。 您可能需要检查程序代码的设计。

RelativeSource works, but I don't think it's right to let controls to prowl across each other's properties. 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.

找回味觉 2024-07-31 17:58:15

使用下面的绑定作为按钮的命令:

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

这将告诉它找到您的 UserControl 并使用其 DataContext。

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.

趁微风不噪 2024-07-31 17:58:15

如果您想要一个肮脏的、破坏 MVVM 的解决方案,请在按钮上设置 Tag="{Binding}" 并处理 Click 事件。 在事件处理程序中,调用 ViewModel 上的命令。

If you want a dirty, MVVM-breaking solution, then set the Tag="{Binding}" on the button and handle the Click event. In the event handler, call the command on your ViewModel.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文