在WPF MVVM模式中更改ListBox MVVM的ItemContainerStyle

时间:2014-12-22 12:10:37

标签: wpf mvvm

我有一个ListBox,它有一个itemcontainerstyle,它有这种风格的背景颜色(比如说绿色),我想改变MVVM的背景颜色。 颜色会在某些特定条件下发生变化,否则应该应用默认颜色(即绿色)。

<ListBox x:Name="lst1" ItemsSource="{Binding DataSource}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" Style="{DynamicResource StepListBox}" ItemContainerStyle="{DynamicResource ListBoxItemStyle}" Margin="-10,0,0,0">
//Listbox Items
</ListBox>

这是我的ListboxItemStyle,它在一个单独的xaml文件中定义

<Style x:Key="ListboxItemStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Margin" Value="20,0,0,10"/>
        <Setter Property="Background" Value="{DynamicResource Green}"/>
        <Setter Property="BorderBrush" Value="{DynamicResource TertiaryMediumStroke}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource SecondaryDark}"/>
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
        <Setter Property="Padding" Value="10,10,0,10"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <Grid Margin="0">
                            <Rectangle x:Name="BgColor" Fill="{DynamicResource TertiaryMediumStroke}" Margin="-10,-10,0,-10" Opacity="0.1"/>
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <!--#FFD1EFD6-->
                            <Setter Property="Background" TargetName="Bd" Value="#FFD7F0DB" />
                            <Setter Property="Opacity" TargetName="BgColor" Value="0" />
                            <Setter Property="Foreground" Value="{DynamicResource ForeLight}"/>
                        </Trigger>
                        <!--
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="Selector.IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        </MultiTrigger>
                        -->
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Opacity" TargetName="BgColor" Value="0" />
                            <Setter Property="Foreground" Value="{DynamicResource ForeDisable}"/>
                            <Setter Property="Background" TargetName="Bd" Value="{StaticResource TertiaryMedium}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

如何在ViewModel中更改此内容?

2 个答案:

答案 0 :(得分:1)

使用MVVM时,视图模型应该对视图一无所知。但是,如果您真的坚持从视图模型更改UI元素颜色,那么您可以遵循此方法。我们的想法是拥有一个或多个具有基本类型的属性,例如boolint,甚至enum,它们是UI中的数据绑定。使用DataTrigger,您的用户界面可以“倾听”。对于这些属性的更改并相应地更新颜色。举个例子:

如果您只有一种或两种颜色可供更新,则可以使用bool属性和一些DataTrigger s:

<Style>
    <Setter Property="Background" Value="White" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsElementRed}" Value="True">
            <Setter Property="Background" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>

如果要更新一系列颜色,可以使用自定义enum

<Style>
    <Setter Property="Background" Value="White" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding EnumInstance}" Value="SomeValue">
            <Setter Property="Background" Value="Red" />
        </DataTrigger>
        ...
        <DataTrigger Binding="{Binding EnumInstance}" Value="SomeOtherValue">
            <Setter Property="Background" Value="Green" />
        </DataTrigger>
    </Style.Triggers>
</Style>

或者,您也可以使用IValueConverterenum实例和各种所需颜色之间进行转换。

答案 1 :(得分:0)

您只需要在ViewModel图层中的布尔值上使用Style中的DataTrigger:

<Style.Triggers>
    <DataTrigger Binding="{Binding MyBooleanProperty, Mode=OneWay}" Value="True">
        <Setter Property="Background" Value="WhatEverColorYouWant"/>
    </DataTrigger>
</Style.Triggers>
<Setter Property="Background" Value="Green"/>

在你的ViewModel中:

public bool MyBool {
    get { return _firstCondition && _secondCondition && _thirdCondition; }
}

当其中一个条件发生变化时,您只想在MyBool上引发NotifyPropertyChanged