Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用父';s数据上下文(WPF-动态菜单命令绑定)_C#_Wpf_Dynamic_Menu_Commandbinding - Fatal编程技术网

C# 使用父';s数据上下文(WPF-动态菜单命令绑定)

C# 使用父';s数据上下文(WPF-动态菜单命令绑定),c#,wpf,dynamic,menu,commandbinding,C#,Wpf,Dynamic,Menu,Commandbinding,我浏览了一下这个网站和谷歌,发现这些解决方案对我不起作用 我在UserControl的ViewModel上有一个命令。好的,usercontrol有一个ItemsControl绑定到一个ObservableCollection。在ItemsControl.ItemTemplate的DataTemplate中,我有一个按钮,我想使用该命令。我无法绑定该命令,因为在DataTemplate中,datacontext不是ViewModel,而是ObservableCollection的一项 问题是:如

我浏览了一下这个网站和谷歌,发现这些解决方案对我不起作用

我在UserControl的ViewModel上有一个命令。好的,usercontrol有一个ItemsControl绑定到一个ObservableCollection。在ItemsControl.ItemTemplate的DataTemplate中,我有一个按钮,我想使用该命令。我无法绑定该命令,因为在DataTemplate中,datacontext不是ViewModel,而是ObservableCollection的一项

问题是:如果丢失了父datacontext,如何将按钮绑定到命令

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

想象一下这样的情景:

您有一个带有observableCollection的ListBox项作为ItemsSource,因此您在ListBox中为集合中的每个元素使用一个datatemplate。好的,您想删除所选项目,并在该作业的每一行中放置一个按钮。你是怎么做到的

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

Button but = e.Source as Button;

if (but != null)
      Presenter.ActualNote = but.DataContext as Note;
简而言之。将行(所选项目)的datacontext发送给演示者

但是,我怎样才能用mvvm的方式来做呢?因为我需要使用命令,但无法将命令分配给按钮,因为按钮对ViewModel(命令存在的位置)一无所知

正如您所看到的,按钮必须存在于datatemplate内部,那么datacontext就不再是ViewModel了。。。。这就是为什么我需要访问父级的DataContext来访问命令

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


谢谢。

将下面的绑定用于按钮的命令:

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

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

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

如果需要脏的、破坏MVVM的解决方案,请在按钮上设置标记=“{Binding}”,并处理单击事件。在事件处理程序中,对ViewModel调用命令。

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

如果您的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;
    }
}

这是我找到的解决方案,但它对我不起作用。如果put:Command=“{Binding DataContext.CommandName,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}}}}”,则其表示应在FindAncestor模式上为RelativeSource指定AncestorType。问题在哪里?谢谢你的回答。我只是在一个样本中尝试了一下,它对我很有效。听起来像是语法错误。你能复制并粘贴你的按钮的XAML吗?哦,没有错误,但是它编译了。我想知道一些简单的事情。我在usercontrol中放置了一个标记元素,并希望在menuitem的标头中以en形式打印它:。但是,visual studio说:找不到引用“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.UserControl',AncestorLevel='1'的绑定源。BindingExpression:Path=Tag;DataItem=null;目标元素是“MenuItem”(名称=“”);目标属性为“Header”(类型为“Object”)而不是为您的类型放置UserControl,请尝试放置控件的类型,如果您的控件名为MyControl,并且您已将xmlns:ctrl映射到其命名空间。太好了,它就像一个符咒!附带说明:如果您仍然希望保留按钮的数据上下文以传递到命令绑定,请使用CommandParameter=“{binding Path=。}”这样,parameter对象就是控件的上下文。我喜欢你的答案,但我需要这个答案。我有一个itemscontrol,里面有一个网格,每个项目都是一个注释。我在网格中有一个上下文菜单,其中有一些关于“selected”的选项注意。每个选项都是一个命令,但菜单的datacontext是实际的注释,而不是viewmodel。我不能将菜单放在外面,因为我需要每个项目的菜单。嗯,是的,我不认为这是一个理想的解决方案,但您可以将ModelView对象作为静态资源放置到窗口中。Resources元素,可能使用ObjectDataProvider,然后引用在任何一个窗口中的任何数据绑定中,都是静态扩展的。我同意,当我使用这个解决方案时,它总是感觉像一个黑客——但是一个有效的黑客。):P.我正在寻找一个很好的解决方案而不会破坏MVVM: P,但是谢谢,它是一个解决方案:PI是一个SL开发者,所以打破MVVM是该课程的标准:我在我的应用程序中使用了半MVVM模式,这很好。最后,我使用了这个解决方案,但没有使用Tag属性。只需单击事件并执行命令,Veeeery dirty,但我需要继续。改天我会尝试另一种解决方案。你能再解释一遍吗?用我的英语,我不明白你想向我解释什么。抱歉,添加了更详细的解释。