在CollectionViewSource

时间:2016-08-27 13:40:23

标签: c# wpf

我需要计算ObservableCollection内可用的联赛数。问题是联盟名称是重复的,所以我需要删除重复项。实际上我的意思是:

private static ObservableCollection<Models.Event> _matches = new ObservableCollection<Models.Event>();

public ObservableCollection<Models.Event> Matches
{
    get { return _matches; }
}

基本上我是一系列活动,现在每个活动都有一个联盟。我的想法是创建另一个名为LeaguesCount的属性:

public int LeaguesCount
{
   //remove duplicate record from _matches here
}

并返回可用的联赛,但还有另一个问题。因为每个联赛都不同,所以我可以:

Premier League x3
Serie A x5
Super League x4
...

我需要将计数数字分开。注意到这个联盟是一个国家名称的联盟,所以我可以在_matches两个事件中使用这种结构:

事件(1)

match_name = 'Foo';
match_nation = 'England';
match_league = 'Premier League';

事件(2)

match_name = 'Test';
match_nation = 'England';
match_league = 'Premier League';

活动(3)

match_name = 'Another event';
match_nation = 'England';
match_league = 'Championship';

所以你可以在England国家/地区看到有三个Premier League联盟名称和Championship联盟名称的活动,我需要从国家England获得所有联赛当然都避免重复。

事件的结构基本上是这样的:

public class Event : ViewModel
{
     private string _matchNation,
                    _matchLeague,
                    _matchName;
}

每个字段都有一个相关的属性。与此问题相关的属性是:

public string MatchNation
    {
        get { return _matchNation; }
        set
        {
            _matchNation = value;
            OnPropertyChanged();
        }
    }
    public string MatchLeague
    {
        get { return _matchLeague; }
        set
        {
            _matchLeague = value;
            OnPropertyChanged();
        }
    }
    public string MatchName
    {
        get { return _matchName; }
        set
        {
            _matchName = value;
            OnPropertyChanged();
        }
    }

想要的结果:

England -> League count (2) [Championship, Premier League]

主要问题是不同的国家名称,因为我在xaml中绑定源代码如下:

<CollectionViewSource Source="{Binding Matches}" x:Key="GroupedItems">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="MatchNation" />
            </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

GroupHeaderTemplate

<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="White" FontSize="22" VerticalAlignment="Bottom" />
                                                            <TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Orange" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />

但是ItemCount实际上会返回所有项目数(事件),而不是没有重复的联赛,这是一个错误。

1 个答案:

答案 0 :(得分:1)

你这让我真的有点头疼。 不幸的是,你的模型不适合这样做。我对它们进行了一些修改(我懒得在任何地方实施INotifyPropertyChanged):

<强>模型

 public class Country {

        public Country() {
            this.Leagues = new ObservableCollection<League>();
        }
        public string Name { get; set; }

        public ObservableCollection<League> Leagues { get; }

    }

    public class League {

        public League() {
            this.Events = new ObservableCollection<Event>();
        }
        public string Name { get; set; }

        public ObservableCollection<Event> Events { get; }
    }

    public class Event : INotifyPropertyChanged {
        private string _matchName;
        public string MatchName {
            get { return _matchName; }
            set {
                _matchName = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        }
    }

带有演示数据的ViewModel

public partial class VM {

        public VM() {
            var eng = new Country() {Name = "England"};
            var l1 = new League() {Name = "Championship" };
            l1.Events.Add(new Event() {MatchName = "Another event" });
            var l2 = new League() { Name = "Premier League" };
            l2.Events.Add(new Event() { MatchName = "Foo" });
            l2.Events.Add(new Event() { MatchName = "Bar" });
            eng.Leagues.Add(l1);
            eng.Leagues.Add(l2);
            this.Countries.Add(eng);

        }

        private ObservableCollection<Country> _countries = new ObservableCollection<Country>();

        public ObservableCollection<Country> Countries {
            get { return _countries; }
        }

    }

<强> CollectionViewSource

<CollectionViewSource Source="{Binding Countries}" x:Key="GroupedItems">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Name" />
            </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

<强>的ListView

<ListView ItemsSource="{Binding Source={StaticResource GroupedItems}}">
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <WrapPanel DataContext="{Binding Items}">
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="22" VerticalAlignment="Bottom" />
                            <TextBlock Text="->" Margin="10,0,0,0" FontWeight="Bold" FontSize="22" VerticalAlignment="Bottom"/>
                            <TextBlock Text="League count" Margin="10,0,0,0" FontWeight="Bold" FontSize="22" VerticalAlignment="Bottom"/>
                            <TextBlock Text="{Binding Leagues.Count}" FontWeight="Bold" FontSize="22" VerticalAlignment="Bottom" Margin="10,0,0,0" />
                            <ItemsControl ItemsSource="{Binding Leagues}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Name}" FontSize="22" Foreground="Orange" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <WrapPanel></WrapPanel>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                            </ItemsControl>
                        </WrapPanel>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel DataContext="{Binding Leagues}">
                    <ItemsControl ItemsSource="{Binding}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}"></TextBlock>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>

                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

<强>结果

Result

注意

如您所见,可以修改Groupheader下方显示的项目(标记为黄色)。 要做到这一点,你必须每次更改面板的DataContext(我很确定,没有别的办法)。

<强>封闭

不漂亮但工作。您可能需要使用XAML以满足您的需求