首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF在CompositeCollection中绑定MenuItem不起作用

WPF在CompositeCollection中绑定MenuItem不起作用
EN

Stack Overflow用户
提问于 2012-07-24 15:31:16
回答 3查看 3.3K关注 0票数 3

我在将命令绑定到组合集合中的菜单项时遇到问题。MenuItem是在UserControl.Resources中定义的ContextMenu的一部分。

问题是新标签的绑定不起作用。当我将MenuItem放在复合集合的外部时,它将会工作。有什么想法吗?

代码语言:javascript
复制
<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/>
EN

回答 3

Stack Overflow用户

发布于 2012-07-25 18:10:17

之所以会发生这种情况,是因为ContextMenu与其包含的父级不在同一个visual tree中,从而导致数据绑定问题。由于ContextMenu不在同一个可视化树中,因此ElementNameRelativeSouce (FindAncestor)等绑定将不起作用。

您可以通过以下方式解决此问题

UserControl的代码后台中的

NameScope.SetNameScope(DataGridRowContextMenu,NameScope.GetNameScope( this ));

  • 使用如下的PlacementTarget属性-

DataContext="{Binding PlacementTarget,RelativeSource={RelativeSource Self}}">。。。

或使用其他解决方案-

ElementName Binding from MenuItem in ContextMenu

WPF: DataContext for ContextMenu

票数 1
EN

Stack Overflow用户

发布于 2015-08-20 15:45:34

我在这个疯狂的ContextMenu和它的MenuItems上挣扎了很长一段时间。但我找到了一个解决方案,可以使用它创建一个自定义行为"BindingProxyBehaviour“,其中包含一个名为"Data”的依赖属性。这个属性包含一个对象,例如您的DataContext(如果您使用MVVM模式,则可能是您的ViewModel )。

代码语言:javascript
复制
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); }
    }
}

只需将BindingProxy作为资源添加到xaml文件中,如下所示。

代码语言:javascript
复制
<UserControl.Resources>
    <ResourceDictionary>
        <behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModel" Data="{Binding}"/>
        <behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModelDynamicDataList" Data="{Binding 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中:

代码语言:javascript
复制
<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>

我希望我能在这篇简短的帖子中帮助一些人。

票数 1
EN

Stack Overflow用户

发布于 2013-01-09 00:57:38

使用CommandTarget属性或创建数据上下文的staticRessource,如下所示

代码语言:javascript
复制
<MenuItem Header=" New label..." 
          Command="{Binding Path=NewLabel,Source={StaticResource viewModel}}"/>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11626114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档