-2

I am trying to create a ContextMenu that defines some filters via Checkable MenuItems, with a Separator separating the last MenuItem from the previous ones.

I know I could define and manage the MenuItems and the Separator in the following way:

<ContextMenu HasDropShadow="False" Placement="Bottom">
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked1}" Header="Filter 1"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked2}" Header="Filter 2"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked3}" Header="Filter 3"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked4}" Header="Filter 4"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked5}" Header="Filter 5"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked6}" Header="Filter 6"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked7}" Header="Filter 7"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked8}" Header="Filter 8"/>
    <Separator Styles.Separator="Default"/>
    <MenuItem IsCheckable="True" IsChecked="{Binding Path=IsChecked9}" Header="Active"/>
</ContextMenu>

But I would rather try to avoid having 9 IsChecked properties in my ViewModel, on top of having the next dev need to add/remove a MenuItem and its associated property when we need to add/remove a filter.

What I'd rather do, is to use the ItemsSource property of the ContextMenu and define an ItemTemplate for each element of the ItemsSource. Unfortunately, if I do this, I am not sure how I can define the Separator before the last element of the ItemsSource like I could do in the previous code snippet.

Is there a way to achieve what I want to do without defining manually each individual MenuItem and its associated properties in the ViewModel?

Choub890
  • 1,163
  • 1
  • 13
  • 27
  • 1
    Your question is unclear. Fundamentally, you will have to at some point manipulate the source collection itself, because if you bind `ItemsSource`, you can't modify the `ItemsControl` collection directly. But there's not enough information in your question to know what approach would be good. Ideally, your binding source collection can accommodate a marker for the separator, which then would use a different template. If that doesn't work, you might have to wrap your original collection in one that inserts the appropriate marker. Please improve the question. See [mcve] and [ask]. – Peter Duniho Jul 21 '20 at 16:49
  • given the `ItemsSource` approach it's easy to differentiate between `MenuItem` and `Separator`. you just need to try it first and then ask the question with the non-working code. – Bizhan Jul 21 '20 at 16:54
  • See the posts which aren't marked as answer here: https://stackoverflow.com/questions/31214027/how-to-correctly-bind-a-viewmodel-which-include-separators-to-wpfs-menu – Andy Jul 21 '20 at 17:11
  • @PeterDuniho I am not sure how I can be clearer based on the links you have provided. I think my title is clear enough, I provided a code snippet of what I am trying to achieve in a way that I deem not acceptable for reasons I have listed (but it does work), and I am suggesting that I could use ```ItemsSource``` as an alternative approach to generate the ```MenuItem```s (granted, I can paste a code snippet for this, which I didn't) which cause a problem I don't know how to resolve (I don't know how to introduce the Separator that way). – Choub890 Jul 21 '20 at 18:58

1 Answers1

0

Based on the following answer: How do I dynamically bind and statically add MenuItems?

I found an hybrid approach to what I wanted to achieve, which makes sense in my context: the only MenuItem I need to manually add is the last one, which I need to handle differently anyway in my ViewModel, so I don't mind manually adding that one. All the others are however generated automatically based on my AllFiltersExceptTheLastOne ObservableCollection:

<UserControl.Resources>
    <CollectionViewSource x:Key="AllFiltersExceptTheLastOne" Source="{Binding Path=Filters}"/>
</UserControl.Resources>
...
<Button.ContextMenu>
    <ContextMenu HasDropShadow="False" Placement="Bottom">
        <ContextMenu.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Source={StaticResource AllFiltersExceptTheLastOne}}" />
                <Separator Margin="0,5,0,5" Styles.Separator="Default"/>
                <MenuItem Padding="2,2,2,2" IsCheckable="true" IsChecked="{Binding Path=Filter.IsChecked}" Header="{Binding Path=Filter.Status}" />
             </CompositeCollection>
         </ContextMenu.ItemsSource>
         <ContextMenu.ItemContainerStyle>
             <Style>
                 <Setter Property="MenuItem.Padding" Value="2,2,2,2"/>
                 <Setter Property="MenuItem.IsCheckable" Value="true"/>
                 <Setter Property="MenuItem.Header" Value="{Binding Path=Status}"/>
                 <Setter Property="MenuItem.IsChecked" Value="{Binding Path=IsChecked}"/>
             </Style>
         </ContextMenu.ItemContainerStyle>
     </ContextMenu>
</Button.ContextMenu>
Choub890
  • 1,163
  • 1
  • 13
  • 27