c# - 具有聚合值和 ProgreessBar 顺序的 WPF ListView 列
问题描述
我有包含价格、大小和总计列的 ListView。价格和尺寸列是绑定到我的项目
public ObservableCollection<MyItem> Book { get; } = new ObservableCollection<MyItem>();
在视图模型中。总列应汇总不同价格的大小,并包含结果和进度条,在最后一项上变化高达 100%。例如:
Price,Size,Total
10,2,59 (progress bar 100%)
9,6,57 (progress bar 97%)
8,5,51 (progress bar 86%)
6,34,46 (progress bar 78%)
2,12,12 (progress bar 20%)
价格有序且独一无二。但是一个问题是总数应该从下面开始。最低价格,应该是聚合时的第一项,是ListView中的最后一项。所以聚合应该使用反向的行顺序来计算,我相信。
如果 ListView 是从 ListView 中的第一项聚合的,那么我可以使用类似的东西:
例子:
Price,Size,Total
10,2,2 (progress bar 3%)
9,6,8 (progress bar 14%)
8,5,13 (progress bar 22%)
6,34,47 (progress bar 80%)
2,12,59 (progress bar 100%)
<local:SumQuantityConverter x:Key="SumQuantityConverter"/>
<DataTemplate DataType="{x:Type local:MyItem}" x:Key="MyItem.Template.ListView.Sum">
<Grid>
<ProgressBar x:Name="pBar" Opacity="0.3" Width="140"
Minimum="0"
Maximum="{Binding DataContext.Sum, ElementName=wind}">
<ProgressBar.Value>
<MultiBinding Converter="{StaticResource SumQuantityConverter}">
<Binding ElementName="wind" Path="DataContext.Book" Mode="OneWay"/>
<Binding Path="Price" Mode="OneWay"/>
<Binding ElementName="wind" Path="DataContext.Sum" Mode="OneWay"/>
</MultiBinding>
</ProgressBar.Value>
</ProgressBar>
<TextBlock Text="{Binding Value, ElementName=pBar, Mode=OneWay}" />
</Grid>
</DataTemplate>
和
<ListView ItemsSource="{Binding Book}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Price}" Header="Price" Width="50"/>
<GridViewColumn DisplayMemberBinding="{Binding Quantity}" Header="Size" Width="60"/>
<GridViewColumn CellTemplate="{Binding Mode=OneWay, Source={StaticResource MyItem.Template.ListView.Sum}}" Header="Total" Width="140"/>
</GridView>
</ListView.View>
</ListView>
转换器:
public class SumQuantityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (!(values?.Length > 2))
return null;
if (!(values[0] is IEnumerable<MyItem> book))
return null;
if (!(values[1] is long price))
return null;
double sum = (double)book.TakeWhile(ord => ord.Price >= price).Sum(ord => ord.Quantity);
return sum;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
当总计应该从 ListView 中的最后一项开始时,这种方法不起作用,因为我们从 ListView 的第一项开始,无法返回上一项。
你能给我一个建议,如何执行我的任务吗?
解决方案
要反转ProgressBar
,您可以执行以下操作
(我稍微简化了代码)
public class SumQuantityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values?.Length > 2 && values[0] is IEnumerable<MyItem> book && values[1] is long price && values[2] is long sum)
{
double result = (double)book.TakeWhile(ord => ord.Price > price).Sum(ord => ord.Quantity);
return sum - result;
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => null;
}
推荐阅读
- batch-file - 批量运行 SSH 命令 (Windows)
- r - 如何使用 R 将反应整数传递给闪亮的仪表板
- c++ - 如何在 boost::msm 中实现“BaseState”并访问状态机 (SM) 的后端/前端
- java - 从 HTTP 帖子获取 JSON 值到 TextView
- sparql - GraphDB - 具有两个连接的非常慢的 sparql 查询
- bioinformatics - 影子规则上的 Snakemake 错误
- encryption - AWS EMR - 使用正确的加密密钥写入 S3
- html - 在 IE11 中打印到默认打印机
- c# - c#中的dialogflow简单实现webhook不起作用
- viewport - 我想在为作为目标空白打开的页面打开的页面中设置视口