DynamicData - Как связать с сгруппированными данными - PullRequest
0 голосов
/ 30 августа 2018

Я использую DynamicData от Roland Pheasant.

DynamicData

Я хотел бы преобразовать мои обычные коллекции C # в Rx.

С ObservableCollection<Grouping<string, DisplayItem>>

в формате DynamicData

ReadOnlyObservableCollection<IGroup<DisplayItem, string>> или ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>

для кэшированного источника.

В настоящее время мой xaml будет выглядеть следующим образом для привязки к обычному ObservableCollection<Grouping<string, DisplayItem>>

<CollectionViewSource x:Name="GroupedDataCollection" Source="{x:Bind ViewModel.bindingData_grouped, Mode=OneWay}" IsSourceGrouped="True" />

        <ListView 
                      Margin="16,0"
                      ItemsSource="{x:Bind GroupedDataCollection.View , Mode=OneWay}"
                      SelectionMode="None">

            <ListView.GroupStyle>
                <GroupStyle HidesIfEmpty="False">
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock FontSize="14"
                                           FontWeight="SemiBold"
                                           Text="{Binding  Key }" />

                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>

            <ListView.ItemTemplate >
                <DataTemplate x:DataType="viewmodels:DisplayItem">
                    <StackPanel>

                        <TextBlock FontSize="14"
                                       FontWeight="SemiBold"
                                       Text="{x:Bind Description  }" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

Модель:

    public class DisplayItem {
    public string ID { get; set; } = Guid.NewGuid().ToString();
    public string Type { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public double? Price { get; set; } = 0; }

Существующие результаты c # Observable Collection: Existing results

Код динамических данных:

public ReadOnlyObservableCollection<IGroup<DisplayItem, string>> bindingData_grouped;

var myBindingOperation_grouped = Data.ToObservableChangeSet() .GroupOn(x => x.Type) .ObserveOn(RxApp.MainThreadScheduler) .Bind(out bindingData_grouped) .Subscribe();

Используя приведенный выше код, если я связываюсь с ReadOnlyObservableCollection<IGroup<DisplayItem, string>> или ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>, мой просмотр списка ничего не показывает.

Как связать из списка xaml с помощью «CollectionViewSource» в ReadOnlyObservableCollection<IGroup<DisplayItem, string>> или ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>

спасибо заранее.

1 Ответ

0 голосов
/ 22 октября 2018

Я новичок в DynamicData, поэтому, возможно, я заново внедряю что-то, что уже существует в lib, но вот что я придумал:

// custom IGrouping implementation which is required by ListView
public class Grouping<TKey, TElement> : ObservableCollectionExtended<TElement>, IGrouping<TKey, TElement>
{
    public Grouping(IGroup<TElement, TKey> group) 
    {
        if (group == null)
        {
            throw new ArgumentNullException(nameof(group));
        }

        Key = group.GroupKey;
        group.List.Connect().Bind(this).Subscribe();
    }

    public TKey Key { get; private set; }
}

// this.Ints is an ObservableCollection<int> which I manipulate thru UI
this.Ints
    .ToObservableChangeSet()
    .GroupOn(i => (int)(i / 10)) // group by 10s
    .Transform(group => new Grouping<int, int>(group)) // transform DynamicData IGroup into our IGrouping implementation
    .Sort(SortExpressionComparer<Grouping<int, int>>.Ascending(t => t.Key)) // sort by keys
    .ObserveOnDispatcher()
    .Bind(this.GroupedInts) // this.GroupedInts is used as binding source for CollectionViewSource in UI
    .Subscribe();

private ObservableCollectionExtended<Grouping<int, int>> GroupedInts { get; } = new ObservableCollectionExtended<Grouping<int, int>>();

По сути, вам нужна пользовательская реализация интерфейса IGrouping, требуемая механизмом группировки ListView (CollectionViewSource's). Вы передаете ему экземпляр IGroup (который происходит из метода GroupOn DynamicData). В конструкторе вы соединяете () с ReactiveList группы и связываете его с самим Grouping.

...