首页 > 解决方案 > ResourceDictionary 中的 WPF CollectionViewSource

问题描述

我在 ResourceDictionary 文件中有 CollectionViewSource。

菜单项.xaml

    <!--This code is not working-->
<CollectionViewSource Source="{Binding DynamicMenuItems, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" x:Key="DynamicMenuItems"/>

    <Style x:Key="DynamicMenuItemStyle" TargetType="{x:Type MenuItem}">
        <Setter Property="Header" Value="{Binding Path=Header}" />
    </Style>
    
    <Style x:Key="DynamicMenu" TargetType="{x:Type MenuItem}" >
        <Setter Property="Header" Value="Dynamic Menu" />
        <!--<Setter Property="ItemsSource" Value="{Binding Source={StaticResource DynamicMenuItems}}" />-->
        <Setter Property="ItemContainerStyle" Value="{StaticResource DynamicMenuItemStyle}" />
        <Setter Property="ItemsSource">
            <Setter.Value>
                <CompositeCollection>
                    <CollectionContainer Collection="{Binding Source={StaticResource DynamicMenuItems}}" />
                    <Separator />
                    <MenuItem Header="Static Menu Item" />
                </CompositeCollection>
            </Setter.Value>
        </Setter>
    </Style>

主窗口.xaml

<Window.Resources>
    <!--This code is working-->
    <CollectionViewSource Source="{Binding DynamicMenuItems}" x:Key="WindowResourceDynamicMenuItems"/>

    <Style x:Key="WindowResourceDynamicMenu" TargetType="{x:Type MenuItem}" >
        <Setter Property="Header" Value="Dynamic Menu" />
        <Setter Property="ItemContainerStyle" Value="{StaticResource DynamicMenuItemStyle}" />
        <Setter Property="ItemsSource">
            <Setter.Value>
                <CompositeCollection>
                    <CollectionContainer Collection="{Binding Source={StaticResource WindowResourceDynamicMenuItems}}" />
                    <Separator />
                    <MenuItem Header="Static Menu Item" />
                </CompositeCollection>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid Background="WhiteSmoke">
    <Grid.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Dynamic Menu Items" Style="{StaticResource WindowResourceDynamicMenu}"/>
            <MenuItem Header="Resource Dictionary Dynamic Menu Items" Style="{StaticResource DynamicMenu}"/>
            <MenuItem Header="Static Menu Item" />
        </ContextMenu>
    </Grid.ContextMenu>
</Grid>

菜单模型.cs

public class MenuModel
{
    public string Header { get; set; }

    public MenuModel(string header)
    {
        Header = header;
    }
}

主视图模型.cs

public class MainViewModel
{ 
    public ObservableCollection<MenuModel> DynamicMenuItems { get; set; }

    public MainViewModel()
    {
        DynamicMenuItems = new ObservableCollection<MenuModel>();
        DynamicMenuItems.Add(new MenuModel("Dynamic Menu 1"));
        DynamicMenuItems.Add(new MenuModel("Dynamic Menu 2"));
        DynamicMenuItems.Add(new MenuModel("Dynamic Menu 3"));
    }
}

主窗口.cs

public partial class MainWindow : Window
{
    MainViewModel model = null;
    public MainWindow()
    {
        InitializeComponent();

        model = new MainViewModel();
        DataContext = model;
    }
}

问题是当 CollectionViewSource 位于 <Window.Resources> 中时,动态菜单项加载正常。但它不适用于 ResourceDictionary.xaml

在此处输入图像描述

这是我得到的 XAML 绑定错误。

在此处输入图像描述

如果我将 ObservableCollection DynamicMenuItems直接绑定到 MenuItem,那么我可以看到动态菜单项。

谁能建议我我在做什么错?

标签: wpfresourcedictionarycollectionviewsource

解决方案


ACollectionViewSource没有添加到可视化树中,因此它没有可以使用 a 绑定到的可视祖先{RelativeSource}

但是您应该能够DataContext直接绑定到当前,就像您在原始 XAML 标记中所做的那样:

<CollectionViewSource Source="{Binding DynamicMenuItems}" x:Key="DynamicMenuItems"/>

只需将工作标记移动到资源字典并按原样使用它。


推荐阅读