You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WPF ListView中根据Item类外条件显示Yes/No列值?

问题

我有一个简单的模型类:

public class Car
{
    public string Make { get; init; }
    public string Model { get; init; }
    public string Year { get; init; }
}

ViewModel里有两个列表:

public class ViewModel
{
    public ObservableCollection<Car> Cars { get; }
    public List<Car> CanBeSold { get; }

    public ViewModel()
    {
        Car car1 = new() { Make = "Toyota", Model = "Corolla", Year = "2020" };
        Car car2 = new() { Make = "Honda", Model = "Civic", Year = "2021" };
        Car car3 = new() { Make = "Mitsubishi", Model = "Lancer", Year = "2017" };

        Cars = new();
        CanBeSold = new();

        Cars.Add(car1);
        Cars.Add(car2);
        Cars.Add(car3);

        CanBeSold.Add(car2);
    }
}

视图中把ListView绑定到Cars集合:

<ListView ItemsSource="{Binding Cars}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Make" DisplayMemberBinding="{Binding Path=Make}"/>
            <GridViewColumn Header="Model" DisplayMemberBinding="{Binding Path=Model}"/>
            <GridViewColumn Header="Year" DisplayMemberBinding="{Binding Path=Year}"/>
            <GridViewColumn Header="Can Be Sold"/>
        </GridView>
    </ListView.View>
</ListView>

怎么实现根据Car是否在CanBeSold列表中,在“Can Be Sold”列显示“Yes/No”?


实现方案

方案一:用多值转换器(符合MVVM,推荐)

这是最规范的做法,不会破坏模型和ViewModel的职责分离:

  1. 先写一个多值转换器类,用来判断当前Car是否在CanBeSold集合里:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;

public class CarCanBeSoldConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[0] is Car car && values[1] is List<Car> canBeSoldList)
        {
            return canBeSoldList.Contains(car) ? "Yes" : "No";
        }
        return "No";
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  1. 在XAML的资源里声明这个转换器(记得替换YourProjectNamespace为你实际的项目命名空间):
<Window.Resources>
    <xmlns:local="clr-namespace:YourProjectNamespace"/>
    <local:CarCanBeSoldConverter x:Key="CarCanBeSoldConverter"/>
</Window.Resources>
  1. 修改ListView的“Can Be Sold”列,用MultiBinding把当前Car和ViewModel的CanBeSold集合传给转换器:
<GridViewColumn Header="Can Be Sold">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding Converter="{StaticResource CarCanBeSoldConverter}">
                        <Binding/> <!-- 绑定当前行的Car对象 -->
                        <Binding Path="DataContext.CanBeSold" RelativeSource="{RelativeSource AncestorType=ListView}"/> <!-- 绑定ViewModel里的CanBeSold列表 -->
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

方案二:在ViewModel里加判断方法(简单直接)

如果不想写转换器,也可以在ViewModel里加个判断方法,再配合布尔转文本的小转换器:

  1. 在ViewModel里添加判断方法:
public bool IsCarCanBeSold(Car car)
{
    return CanBeSold.Contains(car);
}
  1. 写一个布尔转Yes/No的转换器:
using System;
using System.Globalization;
using System.Windows.Data;

public class BoolToYesNoConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is bool b && b ? "Yes" : "No";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  1. 在XAML资源里声明这个转换器,然后修改列的绑定:
<Window.Resources>
    <xmlns:local="clr-namespace:YourProjectNamespace"/>
    <local:BoolToYesNoConverter x:Key="BoolToYesNoConverter"/>
</Window.Resources>

<!-- 修改后的Can Be Sold列 -->
<GridViewColumn Header="Can Be Sold">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DataContext.IsCarCanBeSold(.), RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource BoolToYesNoConverter}}"/>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

方案三:给Car模型加属性(不推荐,耦合性高)

如果项目很小,不在意耦合,可以直接给Car加个IsCanBeSold属性,在ViewModel里赋值:

  1. 修改Car模型:
public class Car
{
    public string Make { get; init; }
    public string Model { get; init; }
    public string Year { get; init; }
    public bool IsCanBeSold { get; set; }
}
  1. 在ViewModel构造函数里设置属性:
public ViewModel()
{
    Car car1 = new() { Make = "Toyota", Model = "Corolla", Year = "2020" };
    Car car2 = new() { Make = "Honda", Model = "Civic", Year = "2021", IsCanBeSold = true };
    Car car3 = new() { Make = "Mitsubishi", Model = "Lancer", Year = "2017" };

    // ... 原有添加集合的代码
}
  1. 直接绑定属性加转换器:
<GridViewColumn Header="Can Be Sold" DisplayMemberBinding="{Binding IsCanBeSold, Converter={StaticResource BoolToYesNoConverter}}"/>

(同样需要声明BoolToYesNoConverter)


内容的提问来源于stack exchange,提问作者AntikM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:32:55