根据 ViewModel 上的 属性 更改 ListBoxItem 颜色

Changing ListBoxItem colour based on Property on ViewModel

我有一个这样的列表框:

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

Users 是 User 的 Observable 集合,它是一个 class,具有 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 不是依赖项 属性。但我想做这样的事情。

使用多值转换器并传递两个值并比较它然后 return 值。

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

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

转换器:

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

这里你会通过参数收到两个名字,所以你可以比较return你想要的颜色。

你通过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 中检索了当前人的用户名,为此我需要指定对象在哪里,这就是 relativeSource 的原因。

在第二个绑定中,我直接获取了 ListItemBox DataContext 的 属性 UserName,它绑定了一个 Person 类型的对象。

就是这样,它按预期工作。