-1

I've CollectionViewSource in ResourceDictionary file.

MenuItems.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>

MainWindow.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>

MenuModel.cs

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

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

MainViewModel.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"));
    }
}

MainWindow.cs

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

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

The problem is dynamic menu items are loading fine when CollectionViewSource is in <Window.Resources>. But it is not working from ResourceDictionary.xaml

enter image description here

Here is the XAML binding error I get.

enter image description here

If I bind ObservableCollection DynamicMenuItems directly to MenuItem then I can see Dynamic menu items.

Can anyone suggest me what's wrong am I doing?

E_net4
  • 27,810
  • 13
  • 101
  • 139
Krish
  • 616
  • 9
  • 19

1 Answers1

0

A CollectionViewSource is not added to the visual tree and hence it has no visual ancestors that you can bind to using a {RelativeSource}.

But you should be able to bind to the current DataContext directly, just as you did in your original XAML markup:

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

Just move the working markup to the resource dictionary and use it as-is.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Not working but now error is different. `Cannot find governing FrameworkElement or FrameworkContentElement for target element` – Krish Apr 22 '21 at 10:36