我有一个WPF应用程序,我需要实现这个概念:
有combobox
和datagrid
。 combobox
包含卖家列表,数据网格包含他们销售的商品的费率。
我想要这样的事情:
client -> null
item | rate
--------------------
itemA | 0.00
itemB | 0.00
itemC | 0.00
如果未选择client
(卖家),则items
的所有费率均默认为0.00。
现在,我们假设我选择client
名称为clientA
,但不会卖ItemB
。然后,显示应反映这一点。
client -> clientA
item | rate
--------------------
itemA | 5.00
itemB | 0.00
itemC | 8.00
基本上,对于null
而items
client
不出售,它应该显示0.00而不是Dictionary
。
这实际上是WPF
的工作,如果是ObservableDictionary
,则为Caliburn
。
但是,我正在使用BindableCollection
,我想使用if (SelectedReferenceClient == null)
{
Rates = new BindableCollection<KeyValuePair<string, decimal>>(itemrepository.FindWhere(c => true).Select(c => new KeyValuePair<string, decimal>(key: c.Name, value: 0)));;
} //retrieve all items and put value to zero.
var SelectedClientRates = new List<KeyValuePair<string, decimal>>(raterepository.FindWhere(c => c.Client == SelectedClient).Select(c => new KeyValuePair<string, decimal>(key: c.ItemName, value: c.Rate)));
//get rates of items they sell
foreach (var a in SelectedClientRates)
{
var b = Rates.FirstOrDefault(c => c.key == a.key);
b.value = a.value;
}//update the values in BindingCollection
来解决它。
所以,我有类似的东西:
LINQ
这可能有用,但它很吵,而且它很笨拙。是否有任何LINQ
方法可以做到这一点?由于BindableCollection
憎恶副作用,我首先想到的是它是不可能的。
但是,如果我想坚持ObservableDictionary
而不使用{{1}},还有更好的方法吗?
答案 0 :(得分:2)
如果创建新的BindableCollection<T>
实例是一个选项(而不是更新现有实例),则可以使用LINQ构建IEnumerable<T>
查询并将其传递给BindableCollection<T>
构造函数重载接受{{ 1}}:
IEnumerable<T>
LINQ部分是2个枚举之间的简单left outer join。左可枚举包含所有项目,并从存储库或已填充的存储中获取,而右可枚举包含所选项目/值对,并从其存储库中获取相应的过滤器。
一旦var keys = SelectedReferenceClient == null ? itemrepository.FindWhere(c => true).Select(c => c.Name) : Rates.Select(rate => rate.Key);
var rates = raterepository.FindWhere(c => c.Client == SelectedClient).Select(c => new KeyValuePair<string, decimal>(key: c.ItemName, value: c.Rate));
var combined = from key in keys
join rate in rates on key equals rate.Key into match
from rate in match.DefaultIfEmpty()
select new KeyValuePair<string, decimal>(key: key, value: rate.Key != null ? rate.Value : 0);
Rates = new BindableCollection<KeyValuePair<string, decimal>>(combined);
运算符完成相关,结果值将根据匹配的存在/不存在来确定 - 匹配值或0.这里唯一不寻常的是匹配存在的检查 - 通常我们使用left outer join
之类的东西,但是因为right != null
是right
(值类型),我们使用结构的字符串成员来达到同样的目的。
答案 1 :(得分:0)
参见下面的示例代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication49
{
class Program
{
static void Main(string[] args)
{
string SelectedClient = "";
List<RateRepository> raterepository = new List<RateRepository>();
Dictionary<string, decimal> SelectedClientRates = raterepository.Where(c => c.Client == SelectedClient)
.GroupBy(x => x.ItemName, y => y.Rate)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
public class RateRepository
{
public string Client { get; set; }
public string ItemName { get; set; }
public decimal Rate { get; set; }
}
}