1

在 WPF 客户端应用程序中,我在使用分层数据模板加载数据绑定菜单项时遇到了一些困难。

首先,我创建了 ViewModel,其中包含菜单项的基本属性:标题、命令、ImageSource(用于图标属性的图像的路径)和子项。

然后,我在 XAML 窗口中创建了视图以显示我的菜单。为了绑定我的集合,考虑到子项,我将分层数据模板用于菜单项模板。

这是 ItemTemplate 的 XAML 代码:

<HierarchicalDataTemplate DataType="{x:Type vm:MenuItemViewModel}" ItemsSource="{Binding Path=Items}">
    <HierarchicalDataTemplate.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Style.Resources>
                <Image x:Key="ItemImage" Source="{Binding ImageSource}" Width="16" Height="16" x:Shared="false" />
            </Style.Resources>
            <Style.Setters>
                <Setter Property="Command" Value="{Binding Command}" />
                <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
                <Setter Property="Icon" Value="{StaticResource ItemImage}" />
            </Style.Setters>
        </Style>
    </HierarchicalDataTemplate.ItemContainerStyle>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Title}" />
    </StackPanel>
</HierarchicalDataTemplate>

当我初始化菜单并显示窗口时,一切看起来都很好。

之后,我尝试将菜单项模板放入资源字典中,以便能够在我的应用程序中的任何位置将其作为默认模板重用。当我这样做时,我抛出了一个异常:

命名空间“http://schemas.microsoft.com/winfx/2006/xaml”中的共享属性只能在编译的资源字典中使用。

在花了这么多时间寻找解决方案之后,我终于制作了一个测试项目(可在此处获得)来演示该问题。

我不知道如何使我的资源字典成为编译资源字典......有人可以帮助我吗?

4

2 回答 2

0

找到了解决方案,实现了一个转换器:

public class MenuIconConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return Binding.DoNothing;

        string imageUri = value.ToString();

        if (string.IsNullOrEmpty(imageUri)) return Binding.DoNothing;

        BitmapImage bitmapImage = new BitmapImage(new Uri(imageUri, UriKind.RelativeOrAbsolute)) { DecodePixelHeight = 16, DecodePixelWidth = 16 };

        return new Image() { Height = 16, Width = 16, Source = bitmapImage, SnapsToDevicePixels = true, UseLayoutRounding = true };
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Binding.DoNothing;
    }

    #endregion
}

要使用转换器,应修改 DataTemplate:

<converter:MenuIconConverter x:Key="MenuIconConverter" />

<HierarchicalDataTemplate x:Key="MenuItemTemplate" DataType="{x:Type vm:MenuItemViewModel}" ItemsSource="{Binding Path=Items}">
    <HierarchicalDataTemplate.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Style.Setters>
                <Setter Property="Command" Value="{Binding Command}" />
                <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
                <Setter Property="Icon" Value="{Binding ImageSource, Converter={StaticResource MenuIconConverter}, Mode=OneWay}" />
            </Style.Setters>
        </Style>
    </HierarchicalDataTemplate.ItemContainerStyle>
    <TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>

有了这个,一切正常。我期待没有代码的解决方案,但这似乎是不可能的:(

于 2012-09-11T06:46:01.083 回答
0

尝试x:Shared="false"<Image>元素中删除

于 2012-09-10T11:06:48.030 回答