WPF绑定菜单项中CompositeCollection不工作 [英] WPF Binding a MenuItem in a CompositeCollection not working

查看:366
本文介绍了WPF绑定菜单项中CompositeCollection不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题绑定命令以compositecollection一个菜单项。在菜单项是的一部分文本菜单这是在 UserControl.Resources

问题是,新的标签的结合是行不通的。当我把菜单项的复合式集合之外它会工作。任何想法?

 < UserControl.Resources>
    <文本菜单X:键=DataGridRowContextMenu>
        <菜单项标题=设置标签/>
            < MenuItem.ItemsSource>
                    < CompositeCollection>
                            < CollectionContainer收集={绑定源= {StaticResource的labelsSelectSource}}/>
                    <菜单项标题=新建标签...
                          命令={结合DataContext.NewLabel,
                                的RelativeSource = {的RelativeSource模式= FindAncestor,
                                AncestorType = {X:类型用户控件}}}/>                        < / CompositeCollection>
                 < /MenuItem.ItemsSource>
            < /菜单项>
< UserControl.Resources />


解决方案

我跟上这个疯狂的ContextMenu及其周围的MenuItems挣扎了很长一段时间。但是,我发现了一个解决方案,它创建一个自定义的行为BindingProxyBehaviour与名为数据dependancyproperty工作。这个属性保存,例如一个对象的DataContext的(也许您的视图模型,如果你使用MVVM模式)。

 公共类BindingProxyDataBehavior:可冻结
{
    公共静态只读的DependencyProperty DataProperty =
        DependencyProperty.Register(数据的typeof(对象)的typeof(BindingProxyDataBehavior),新UIPropertyMetadata(NULL));    保护覆盖可冻结CreateInstanceCore()
    {
        返回新BindingProxyDataBehavior();
    }    公共对象数据
    {
        {返回(对象)的GetValue(DataProperty); }
        集合{的SetValue(DataProperty,值); }
    }
}

只需添加BindingProxy作为资源在你XAML文件是这样的。

 < UserControl.Resources>
    <&ResourceDictionary中GT;
        <行为:BindingProxyDataBehavior X:键=BindingProxyViewModel数据={结合}/>
        <行为:BindingProxyDataBehavior X:键=BindingProxyViewModelDynamicDataList数据={结合DynamicDataListObject}/>
    < / ResourceDictionary的>
< /UserControl.Resources>

在我的情况下,我使用的是CompositeCollection混淆了静态和动态的MenuItems。因此与关键的第二资源BindingProxyViewModelDynamicDataList。

瞧,现在你可以很容易地访问您的数据无论在哪里你的ContextMenu是。
在XAML树我ContexMenu位置UserControl->Grid->DataGrid->DataGridTemplateColumn->CellTemplate->DataTemplate->TextBox.Template->Grid->TextBlock->controls:IconButton(simple的CustomButton控制按钮从派生),在这里我们是IconButton内:

 <控制:IconButton.ContextMenu>
<文本菜单X:NAME =AnyContextMenuName>
    < ContextMenu.Resources>
        < HierarchicalDataTemplate数据类型={X:类型DynamicDataListItemType}>
            < TextBlock的文本={结合DynamicDataListItemProperty}/>
        < / HierarchicalDataTemplate>
    < /ContextMenu.Resources>
    < ContextMenu.ItemsSource>
        < CompositeCollection>
            < CollectionContainer收集={绑定源= {StaticResource的BindingProxyViewModelDynamicDataList},路径=数据}/>
            <分离器/>
            <菜单项标题=您的静态头命令={绑定源= {StaticResource的BindingProxyViewModel},路径= Data.ViewModelCommandForYourStaticMenuItem}/>
        < / CompositeCollection>
    < /ContextMenu.ItemsSource>
    < ContextMenu.ItemContainerStyle>
        <样式和GT;
            < setter属性=MenuItem.ForegroundVALUE ={DynamicResource DefaultForegroundBrush}/>
            < setter属性=MenuItem.CommandVALUE ={绑定源= {StaticResource的BindingProxyViewModel},路径= Data.ViewModelCommandForDynamicMenuItems}/>
            < setter属性=MenuItem.CommandParameterVALUE ={结合}/>
        < /样式和GT;
    < /ContextMenu.ItemContainerStyle>
< /文本菜单>
< /控制:IconButton.ContextMenu>

我希望我能帮助sombody这个简短文章。

I'm having problems binding a command to a menuitem in a compositecollection. The MenuItem is part of ContextMenu which is defined in the UserControl.Resources.

The problem is that the binding of the New label is not working. When I place the MenuItem outside of the composite collection it will work. Any ideas?

<UserControl.Resources>
    <ContextMenu x:Key="DataGridRowContextMenu">
        <MenuItem Header=" Set label"/>
            <MenuItem.ItemsSource>
                    <CompositeCollection>
                            <CollectionContainer Collection="{Binding Source={StaticResource labelsSelectSource}}" />
                    <MenuItem Header=" New label..." 
                          Command="{Binding DataContext.NewLabel,
                                RelativeSource={RelativeSource Mode=FindAncestor,
                                AncestorType={x:Type UserControl}}}"/>

                        </CompositeCollection>
                 </MenuItem.ItemsSource>
            </MenuItem>
<UserControl.Resources/>

解决方案

I keep struggling around with this crazy ContextMenu and its MenuItems for a long time. But I found a solution to work with it creating a custom behaviour "BindingProxyBehaviour" with a dependancyproperty named "Data". This property holds an object for example your DataContext(maybe your ViewModel if you use MVVM pattern).

public class BindingProxyDataBehavior : Freezable
{
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxyDataBehavior), new UIPropertyMetadata(null));

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxyDataBehavior();
    }

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
}

Just add the BindingProxy as a resource in you xaml file like this.

<UserControl.Resources>
    <ResourceDictionary>
        <behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModel" Data="{Binding}"/>
        <behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModelDynamicDataList" Data="{Binding DynamicDataListObject}"/>
    </ResourceDictionary>
</UserControl.Resources>

In my case I am using a CompositeCollection to mix up static and dynamic MenuItems. Therefore the second resource with key "BindingProxyViewModelDynamicDataList".

Voilà now you can easily access your data no matter where your ContextMenu is. My ContexMenu position in xaml tree is UserControl->Grid->DataGrid->DataGridTemplateColumn->CellTemplate->DataTemplate->TextBox.Template->Grid->TextBlock->controls:IconButton(simple customButton control derived from button) and here we are inside the IconButton:

<controls:IconButton.ContextMenu>
<ContextMenu x:Name="AnyContextMenuName">
    <ContextMenu.Resources>
        <HierarchicalDataTemplate DataType="{x:Type DynamicDataListItemType}">
            <TextBlock Text="{Binding DynamicDataListItemProperty}"/>
        </HierarchicalDataTemplate>
    </ContextMenu.Resources>
    <ContextMenu.ItemsSource>
        <CompositeCollection>
            <CollectionContainer Collection="{Binding Source={StaticResource BindingProxyViewModelDynamicDataList}, Path=Data}"/>
            <Separator/>
            <MenuItem Header="Your static header" Command="{Binding Source={StaticResource BindingProxyViewModel}, Path=Data.ViewModelCommandForYourStaticMenuItem}"/>
        </CompositeCollection>
    </ContextMenu.ItemsSource>
    <ContextMenu.ItemContainerStyle>
        <Style>
            <Setter Property="MenuItem.Foreground" Value="{DynamicResource DefaultForegroundBrush}"/>
            <Setter Property="MenuItem.Command" Value="{Binding Source={StaticResource BindingProxyViewModel}, Path=Data.ViewModelCommandForDynamicMenuItems}"/>
            <Setter Property="MenuItem.CommandParameter" Value="{Binding}"/>
        </Style>
    </ContextMenu.ItemContainerStyle>
</ContextMenu>
</controls:IconButton.ContextMenu>

I hope that I could help sombody with this short post.

这篇关于WPF绑定菜单项中CompositeCollection不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆