ComboBox仅显示ICollectionView中字段的唯一值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ComboBox仅显示ICollectionView中字段的唯一值相关的知识,希望对你有一定的参考价值。

我有一个DataGrid,其ItemSource绑定到ICollectionView(用于过滤)。我正在尝试使用ComboBox来过滤DataGid中的EffectiveDate列,其ItemsSource(下拉值)应该是DataGrid中所有当前可用行(还有其他过滤器)的EffectiveDate。

这是代码:

在MainWindow中:

<DataGrid Name="ProductsList"
          ItemsSource="{Binding PricesView}" AutoGenerateColumns="False">
    <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Sku}" Header="Sku"/>
            <DataGridTextColumn Binding="{Binding Upc}" Header="UPC"/>
            <DataGridTextColumn Binding="{Binding Cost}" Header="Cost"/>
            <DataGridTextColumn Binding="{Binding Map}" Header="MAP"/>
            <DataGridTextColumn Binding="{Binding List.EffectiveDate, StringFormat=d}" Header="List Effective Date"/>
            <DataGridTextColumn Binding="{Binding List.Vendor.Name}" Header="Vendor"/>
    </DataGrid.Columns>
</DataGrid>

<ComboBox ItemsSource="{Binding PricesView}" DisplayMemberPath="List.EffectiveDate"/>

在MainWIndowViewModel中:

public ICollectionView PricesView { get; set; }

public ObservableCollection<Price> Prices { get; set; } = new ObservableCollection<Price>(DataAccess.GetVendorPricing());

public MainWIndowViewModel()
{
    PricesView = CollectionViewSource.GetDefaultView(Prices);
}

价格等级:

public class Price
    {
        public int Id { get; set; }
        public PriceList List { get; set; }
        public string Sku { get; set; }
        public string Description { get; set; }
        public string Upc { get; set; }
        public double Cost { get; set; }
        public double Map { get; set; }
    }

上面的ListPriceList类型:(这里是你找到EffectiveDate财产的地方)

  public class PriceList
    {
        public int Id { get; set; }
        public Vendor Vendor { get; set; }
        public string FileName { get; set; }
        public DateTime EffectiveDate { get; set; }
    }

问题是ComboBox为每一行(数千个!)提供了EffecitveDate,我需要的只是唯一的值。

我尝试this方法,使用IValueConverter,问题是转换器接受整个ICollectionView没有DisplayMemberPath并返回整个集合的明确值(这基本上是一切),我所追求的只是这个特定字段的明确值。

如何让ComboBox仅显示EffectiveDate的唯一值?

答案

你的记录是不可变的吗?如果是这样,您可以在ViewModel上发布一个属性,以使用Linq获取不同的分组值:

    public IEnumerable<DateTime> DistinctDates
    {
        get
        {
            return from item in this.PricesView.Cast<Price>()
                   group item by item.List.EffectiveDate into g
                   select g.Key;
        }
    }

<ComboBox ItemsSource="{Binding DistinctDates}" />

如果可以编辑数据则更加困难,您应该通知“DistinctDate”属性更改或搜索其他方法...

另一答案

从读取器加载数据时在sql中使用distinct

using (SqlConnection conn = new SqlConnection("Your Connectionstring"))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("Your select Query", conn);

                SqlDataReader dr = cmd.ExecuteReader();

                IList<string> listName = new List<string>();
                while (dr.Read())
                {
                    listName.Add(dr[0].ToString());
                }
                listName = listName.Distinct().ToList();
                ComboBox1.DataSource = listName;
            }</string></string>

以上是关于ComboBox仅显示ICollectionView中字段的唯一值的主要内容,如果未能解决你的问题,请参考以下文章

ComboBox仅显示ICollectionView中字段的唯一值

WPF - 格式化ComboBox的显示项

选择后 ComboBox QML 不显示项目文本

读取 SQL 表单元格值,仅更改 ComboBox.text 而不更改 ComboBox 集合项

如何让组合框2显示仅与组合框1中所做的选择相关的记录?

基于过滤的连续形式填充 ComboBox