带有图标的数据绑定菜单

时间:2011-09-03 16:20:47

标签: c# .net wpf xaml data-binding

我有一个简单的标记,如下所示。 DataContext在运行时分配。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" MinHeight="5" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" MinHeight="5" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" MinWidth="5" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" MinWidth="5" />
    </Grid.ColumnDefinitions>

    <Menu Name="GlobalMenu" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
        <Menu.ItemContainerStyle>
            <Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}">
                <Setter Property="Header" Value="{Binding Text}" />
                <Setter Property="Icon">
                    <Setter.Value>
                        <Image Source="{Binding Image}" />
                    </Setter.Value>
                </Setter>
                <Setter Property="ItemsSource" Value="{Binding Children}" />
            </Style>
        </Menu.ItemContainerStyle>
    </Menu>
</Grid>

问题是菜单项图标只是第一次被淹没。所以菜单项仍然存在,文本在那里,我可以通过更改绑定的DataContext对象来更改菜单项文本,因此绑定通常有效,但不绘制图标。由于图标有点大,我注意到不仅没有绘制图标,而且菜单项的大小也缩小了,就像根本没有图标一样。

绑定对象上的图标属性如下所示

    public BitmapImage Image
    {
        get
        {
            byte[] image = _widget.CommandRelation.Command.Element.Image;

            if (image == null)
            {
                return null;
            }

            BitmapImage bitmapImage = new BitmapImage();

            using (MemoryStream stream = new MemoryStream(image))
            {
                bitmapImage.BeginInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.StreamSource = stream;
                bitmapImage.EndInit();
            }

            return bitmapImage;
        }
    }

1 个答案:

答案 0 :(得分:3)

如果在Style中创建对象,则只为使用该样式的所有对象创建一个实例,这不会起作用,因为UI元素不能在多个地方使用。

您可以将Image声明放在某个(已编译的)资源字典中,该资源字典可以从使用Style的位置访问(Style.Resources未编译,因此遗憾的是不起作用)并设置{{ 3}}在false上,当你在Setter.Value中通过StaticResource引用它时,每次创建一个新实例,每个MenuItem都有自己的图标。

e.g。试试这个:

<Menu Name="GlobalMenu" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
    <Menu.Resources>
        <Image x:Key="Icon" x:Shared="False" Source="{Binding Image}" />
    </Menu.Resources>
    <Menu.ItemContainerStyle>
        <Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}">
            <Setter Property="Header" Value="{Binding Text}" />
            <Setter Property="Icon" Value="{StaticResource Icon}"/>
            <Setter Property="ItemsSource" Value="{Binding Children}" />
        </Style>
    </Menu.ItemContainerStyle>
</Menu>