c# - Cambio de plantilla de MenuItem basado en datos enlazados



wpf binding (1)

Puede crear un Style para MenuItem s. Hazlo local para una instancia concreta del menú (colocándolo en los Resources del menú) o colócalo en tu diccionario de recursos:

<Menu ItemsSource="{Binding MenuItems}">
    <Menu.Resources>
        <Style TargetType="MenuItem">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Title}" Value="-">
                    <Setter Property="Template">
                         <Setter.Value>
                            <ControlTemplate>
                                <Separator/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Menu.Resources>
    <Menu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Title}" Background="Red" />
        </HierarchicalDataTemplate>
    </Menu.ItemTemplate>
</Menu>

Básicamente, tengo una Vista que está vinculada a un ViewModel que tiene MenuItems.

Lo que quiero hacer es que cada vez que el título del menú sea "-" quiero colocar un separador.

En teoría, parece que puedo evitar TemplateSelectors, pero si crees que es inevitable, comparte incluso esas soluciones.

Aquí está el XAML:

<Window x:Class="WpfApp1.MenuItemStyle"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MenuItemStyle" Height="300" Width="300">
    <DockPanel>
        <Menu DockPanel.Dock="Top" ItemsSource="{Binding MenuItems}">
            <Menu.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <HierarchicalDataTemplate.Triggers>
                        <DataTrigger Binding="{Binding Title}" Value="-">
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                                        <Separator />
                                    </HierarchicalDataTemplate>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </HierarchicalDataTemplate.Triggers>

                    <TextBlock Text="{Binding Title}" Background="Red" />
                </HierarchicalDataTemplate>
            </Menu.ItemTemplate>

        </Menu>
        <Grid>
        </Grid>
    </DockPanel>
</Window>

Y aquí está el código detrás:

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MenuItemStyle.xaml
    /// </summary>
    public partial class MenuItemStyle : Window
    {
        public MenuItemStyle()
        {
            InitializeComponent();

            this.DataContext = this;
        }

        public ObservableCollection<MenuItem> MenuItems { get; set; } = new ObservableCollection<MenuItem> {
            new MenuItem{ Title = "M1"
                ,Children= new ObservableCollection<MenuItem>{
                    new MenuItem{ Title = "M2"},
                    new MenuItem{ Title = "-"},
                    new MenuItem{ Title = "M3"},
                }
            }
        };
    }

    public class MenuItem
    {
        public string Title { get; set; }   
        public ObservableCollection<MenuItem> Children { get; set; }
    }
}

Busqué una solución en todas partes pero no pude encontrar una solución pragmática.





menu