1

WPFクライアントアプリケーションで、階層データテンプレートを使用してデータバインドされたメニュー項目を読み込むのに問題があります。

最初に、メニュー項目の基本プロパティ(Title、Command、ImageSource(Iconプロパティに使用する画像へのパス)およびサブ項目)を含むViewModelを作成しました。

次に、メニューを表示するために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

要素x:Shared="false"から削除してみてください<Image>

于 2012-09-10T11:06:48.030 に答える
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 に答える