根据ViewModel上的Property更改ListBoxItem颜色

时间:2015-11-06 13:26:58

标签: c# wpf datatrigger

我有一个这样的列表框:

<ListBox ItemsSource="{Binding Users}" SelectedItem="{Binding CurrentSelectedUser}" 
            DisplayMemberPath="Username"/>  

用户是User的Observable集合,该集合包含2个属性UsernamePassword。 然后我在我的视图模型上有一个名为CurrentUser的属性。我想要做的是改变列表框项目的颜色,如果它上面的文本等于CurrentUser.Username。这是我到目前为止所尝试的:

<ListBox ItemsSource="{Binding Users}" SelectedItem="{Binding CurrentSelectedUser}" 
            DisplayMemberPath="Username">
    <ListBox.ItemContainerStyle>
        <Style BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="{x:Type ListBoxItem}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Content.Username}" Value="{Binding CurrentUser.Username}">
                    <Setter Property="Background" Value="Green"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

这不起作用。有没有办法做到这一点?我知道Value不是依赖属性。但是我想做这样的事情。

2 个答案:

答案 0 :(得分:1)

使用多值转换器并传递两个值并进行比较,然后返回值。

答案 1 :(得分:1)

它没有编译,因为value不是依赖属性,表示你不能在非依赖属性中使用绑定。

您可以使用IMultiValueConverter根据收到的参数返回颜色,这是一个例子。

<强>转换器:

public class Converter : IMultiValueConverter
{
    public Converter()
    {

    }

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var currentPersonName = values[0].ToString();
        var listItemPersonName = values[1].ToString();

        return currentPersonName == listItemPersonName ? Brushes.Red : Brushes.Black;
    }

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

在这里,您将通过参数接收两个名称,以便比较并返回所需的颜色。

你通过Multibinding传递这两个值,这里是XAML。

<强> XAML:

 <Window.Resources>
    <local:Converter x:Key="converter"/>
    <Style  x:Key="style" TargetType="ListBoxItem">
        <Setter Property="Foreground">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource converter}">
                    <MultiBinding.Bindings>
                        <Binding Path="DataContext.CurrentPerson.UserName" 
                                 RelativeSource="{RelativeSource AncestorType={x:Type Window}}"/>
                        <Binding Path="UserName"/>
                    </MultiBinding.Bindings>
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<ListBox ItemsSource="{Binding Persons}"
         DisplayMemberPath="{Binding UserName}"
         ItemContainerStyle="{StaticResource style}"
         SelectedItem="{Binding SelectedPerson}">

</ListBox>

我像你一样做了一个样式,但是使用DataTrigger我使用Multibinding来传递要与转换器进行比较的值。

在第一个绑定中,我在viewModel中检索当前人的userName,为此我需要指定对象的位置,这就是relativeSource的原因。

在第二个绑定中,我只是直接得到ListItemBox DataContext的Property UserName,它有一个类型为Person的对象绑定到它。

就是这样,它就像预期的那样工作。

enter image description here