У меня есть ListView с колонками Price, Size и Total. Столбцы «Цена» и «Размер» являются привязками к элементам моего
public ObservableCollection<MyItem> Book { get; } = new ObservableCollection<MyItem>();
в ViewModel. Столбец итога должен суммировать размеры по разным ценам и содержать результат и индикатор выполнения, который изменяется до 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, потому что мы go из первого элемента ListView и не может вернуться к предыдущему элементу.
Не могли бы вы дать совет, как реализовать мою задачу?