6

MVVM パターン (MVVM Light Toolkit) を使用して WPF でアプリケーションを開発しました。

これまでのところ、私のコントロールの一部である MenuItem のセットに関連付けられているスタイルを実行時に変更するまで、問題はありませんでした。(最大 3 つの異なるスタイルを持つことができます)。

MVVM を使用していない場合は、次のコマンドを使用して解決できます。

MenuElement_Left4.Style = (Style)FindResource("MenuButtonTabsLeft");

しかし、私はMVVMで完全にやりたいので、それを達成するためにこれらのテストを行いました:

1)バインディングでスタイルを変更してみてください(これはうまくいきませんでした):

<MenuItem x:Name="MenuElement_Left4" Header="Test" Style="{Binding SelectedStyle}">

ViewModel では次のようになります。

public string SelectedStyle
    {
       get { return this.selectedStyle; }
       set { this.selectedStyle = value; 
             RaisePropertyChanged("SelectedStyle");
           }
    }
    private string selectedStyle;

2) DataTrigger を使用してスタイルを変更します (これも機能していません。例外が発生します ( Style Trigger to Apply another Style )):

<MenuItem.Style>
    <Style TargetType="{x:Type MenuItem}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=TestStyle}" Value="True">
                <Setter Property="Style" Value="{StaticResource  MenuButtonTabsLeftArrow}"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=TestStyle}" Value="False">
                <Setter Property="Style" Value="{StaticResource  MenuButtonTabsLeft}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</MenuItem.Style>

最後に、次のコードを使用してComboxを使用して、なんとか解決しました(ComboBoxを使用してMenuItemのスタイルを変更するだけで、非表示になります)。(実行時に要素のスタイルを変更するにはどうすればよいですか? )からアイデアを得ました:

<MenuItem x:Name="MenuElement_Left4" Header="Test" Style="{Binding ElementName=AvailableStyles, Path=SelectedItem.Tag}">
<ComboBox Name="AvailableStyles" SelectedIndex="{Binding AvailableStylesIndex}" Visibility="Collapsed">
    <ComboBoxItem Tag="{x:Null}">None</ComboBoxItem>
    <ComboBoxItem Tag="{StaticResource MenuButtonTabsLeftArrow}">MenuButtonTabsLeftArrow</ComboBoxItem>
    <ComboBoxItem Tag="{StaticResource MenuButtonTabsLeft}">MenuButtonTabsLeft</ComboBoxItem>
</ComboBox>

そして私のViewModelで:

public int AvailableStylesIndex
{
    get { return this.availableStylesIndex; }
    set
    {
        this.availableStylesIndex = value;
        RaisePropertyChanged("AvailableStylesIndex");
    }
}

よりクリーンな方法を使用したいと思います。助言がありますか?コードの一部は非常に役立ちます。

4

1 に答える 1

9

リソースにスタイルを保持しているため、よりクリーンなアプローチは、次のような最初のアプローチで IMultiValueConverter を使用することです。

ビューモデル

public string SelectedStyle
{
   get { return this.selectedStyle; }
   set { this.selectedStyle = value; 
         RaisePropertyChanged("SelectedStyle");
       }
}
private string selectedStyle;

Xaml:

<MenuItem.Style>
    <MultiBinding Converter="{StaticResource StyleConverter}">
        <MultiBinding.Bindings>
            <Binding RelativeSource="{RelativeSource Self}"/>
            <Binding Path="SelectedStyle"/>
        </MultiBinding.Bindings>
    </MultiBinding>
</MenuItem.Style/>

コンバーターで、必要なスタイルを見つけて適用します

class StyleConverter : IMultiValueConverter 
{
     public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        FrameworkElement targetElement = values[0] as FrameworkElement; 
        string styleName = values[1] as string;

        if (styleName == null)
            return null;

        Style newStyle = (Style)targetElement.TryFindResource(styleName);

        if (newStyle == null)
            newStyle = (Style)targetElement.TryFindResource("MyDefaultStyleName");

        return newStyle;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

この投稿のスティーブン・ロビ​​ンスの回答から抜粋

于 2013-09-19T09:05:47.203 に答える