簡體   English   中英

在ModelView中更改樣式(MVVM + WPF)

[英]Change style in ModelView (MVVM + WPF)

我有一個使用MVVM模式(MVVM Light Toolkit)在WPF中開發的應用程序。

到目前為止,我沒有遇到任何問題,直到在運行時更改與我的一些控件相關聯的樣式,即一組MenuItem。 (它們最多可以有三種不同的風格)。

如果我不使用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更改樣式(這也沒有用。引發異常( 樣式觸發器應用另一個樣式 )):

<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來改變MenuItems的樣式,因此它是不可見的)。 從( 如何在運行時更改元素樣式? )獲得了想法:

<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");
    }
}

我寧願用更干凈的方式。 有什么建議? 一段代碼會非常有用。

既然你在你的資源中保留你的風格,那么更干凈的approch就是首先使用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();
    }
}

從史蒂文羅賓斯的帖子中得出答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM