在我的HierarchicalDataTemplate中使用样式来正确格式化我的MenuItem绑定

时间:2016-02-28 12:35:50

标签: wpf hierarchicaldatatemplate

我有一个分层的数据集,我绑定到一个菜单,它工作正常,但我在堆栈面板中显示菜单项图标和名称,这两个都在菜单的标题部分,这导致奇怪的是因为绑定的menuitems的图标列没有被使用。想知道如何正确格式化我的XAML,以便各种绑定类型的图标实际上绑定到MenuItem的Icon属性,而不是坐在Header部分。

enter image description here

    <Menu x:Name="menu" >
        <Menu.Resources>
            <HierarchicalDataTemplate DataType="{x:Type ODIF:PluginContainer}">
                <HierarchicalDataTemplate.ItemsSource>
                    <MultiBinding>
                        <MultiBinding.Converter>
                            <local:CompositeDeviceCollectionConverter />
                        </MultiBinding.Converter>
                        <Binding/>
                        <Binding Path="Instance.Devices"/>
                    </MultiBinding>
                </HierarchicalDataTemplate.ItemsSource>
                <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
                    <Image Source="{Binding PluginIcon}" Width="16" Height="16">
                        <Image.Style>
                            <Style TargetType="{x:Type Image}">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding PluginIcon}" Value="{x:Null}">
                                        <Setter Property="Visibility" Value="Collapsed" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Image.Style>
                    </Image>
                    <TextBlock Text="{Binding PluginName}"/>
                </StackPanel>
            </HierarchicalDataTemplate>

            <HierarchicalDataTemplate DataType="{x:Type ODIF:OutputDevice}" ItemsSource="{Binding InputChannels}">
                <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
                    <Image Source="{Binding StatusIcon}" Width="16" Height="16">
                        <Image.Style>
                            <Style TargetType="{x:Type Image}">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding StatusIcon}" Value="{x:Null}">
                                        <Setter Property="Visibility" Value="Collapsed" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Image.Style>
                    </Image>
                    <TextBlock Text="{Binding DeviceName}"/>
                </StackPanel>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type ODIF:InputDevice}" ItemsSource="{Binding OutputChannels}">
                <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
                    <Image Source="{Binding StatusIcon}" Width="16" Height="16">
                        <Image.Style>
                            <Style TargetType="{x:Type Image}">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding StatusIcon}" Value="{x:Null}">
                                        <Setter Property="Visibility" Value="Collapsed" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Image.Style>
                    </Image>
                    <TextBlock Text="{Binding DeviceName}"/>
                </StackPanel>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type ODIF:DeviceChannel}">
                <local:ChannelBox Channel="{Binding}" Width="200" Click="ChannelClicked"/>
            </HierarchicalDataTemplate>
        </Menu.Resources>
        <MenuItem x:Name="menuItem" BorderThickness="0" 
                  Width="{Binding ActualWidth, ElementName=menu, Mode=OneWay}" 
                  Height="{Binding ActualHeight, ElementName=menu, Mode=OneWay}" 
                  ItemsSource="{Binding Plugins, ElementName=InputChannelBoxMenuControl}" Padding="0">
            <MenuItem.Header>
                <local:ChannelBox x:Name="SelectedChannelBox" Width="{Binding ActualWidth, ElementName=menuItem, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=menuItem, Mode=OneWay}" Channel="{Binding SelectedChannel, ElementName=InputChannelBoxMenuControl}"/>
            </MenuItem.Header>
        </MenuItem>

    </Menu>

更新:

编辑HierarchicalDataTemplate.ItemContainerStyle为我提供了奇怪的行为,其中层次结构中的最后一个菜单项包含根项目图标: enter image description here

1 个答案:

答案 0 :(得分:0)

我找到了一种基于另一个用户的答案来实现这一目标的方法,该答案已被删除,只需要进行一些修改即可使用我在绑定中使用的各种类型。

这感觉非常&#34; hackish&#34;因此,如果有人想到更好的东西,我希望他们会发布,但在那之前,我已经了解到,有时候你必须欺骗和强化WPF做你想做的事情,并希望它不会破坏道路;

将此添加到我的根菜单项中可以获得我想要的结果:

            <MenuItem.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Style.Resources>
                        <local:IsNullConverter x:Key="isNullConverter"/>
                        <Image x:Key="IconImage" x:Shared="False">
                            <Image.Style>
                                <Style TargetType="{x:Type Image}">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding PluginIcon, Converter={StaticResource isNullConverter}}" Value="False">
                                            <Setter Property="Source" Value="{Binding PluginIcon}" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding StatusIcon, Converter={StaticResource isNullConverter}}" Value="False">
                                            <Setter Property="Source" Value="{Binding StatusIcon}" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Image.Style>
                        </Image>
                    </Style.Resources>
                    <Setter Property="Icon" Value="{StaticResource IconImage}" />
                </Style>
            </MenuItem.ItemContainerStyle>

转换器:

public class IsNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == null);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException("IsNullConverter can only be used OneWay.");
    }
}

enter image description here