Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping ListView WPF

Tags:

c#

listview

wpf

It's frustrating. I had made a Testapplication, which look like this:

View:

<Window.Resources>
        <CollectionViewSource x:Key="GroupedItems" Source="{Binding Viewers}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Sort" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <Grid>
        <ListView
            Width="244"
            Height="184"
            Margin="46,85,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            ItemsSource="{Binding Source={StaticResource GroupedItems}}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock
                                Margin="10,0,0,0"
                                VerticalAlignment="Center"
                                FontWeight="Bold"
                                Text="{Binding Path=Name}" />
                        </StackPanel>
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <Expander
                                            BorderThickness="0"
                                            DataContext="{Binding Items}"
                                            IsExpanded="True">
                                            <Expander.Header>
                                                <StackPanel Orientation="Horizontal">
                                                    <TextBlock
                                                        VerticalAlignment="Top"
                                                        FontSize="22"
                                                        FontWeight="Bold"
                                                        Foreground="Gray"
                                                        Text="{Binding Sort}" />
                                                </StackPanel>
                                            </Expander.Header>
                                            <ItemsPresenter />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>

ViewModel:

public class MainWindowViewModel {
        public ObservableCollection<MainWindowModel.Viewer> Viewers { get; set; }

        public MainWindowViewModel() {
            Viewers = new ObservableCollection<MainWindowModel.Viewer> {
                new MainWindowModel.Viewer {
                    Name = "Hans",
                    Sort = MainWindowModel.SortDir.Admin
                },
                new MainWindowModel.Viewer {
                    Name = "Peter",
                    Sort = MainWindowModel.SortDir.Mod
                },
                new MainWindowModel.Viewer {
                    Name = "Frank",
                    Sort = MainWindowModel.SortDir.Admin
                },
                new MainWindowModel.Viewer {
                    Name = "Bilbo",
                    Sort = MainWindowModel.SortDir.Admin
                },
            };
        }
    }

Model:

public class MainWindowModel {
        public class Viewer {
            public string Name { get; set; }
            public SortDir Sort { get; set; }
        }


        public enum SortDir {
            Admin,
            Mod,
        }
    }

Yeah, everything works. I get the expected result. Expected result


So, now I want to port this "feature" (grouped listview) to my 'real' application, but I dont get it to work with grouping. For more details, my View:

<controls:MetroContentControl.Resources>
        <CollectionViewSource x:Key="GroupedItems" Source="{Binding ChatHandler.Viewers}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Type" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </controls:MetroContentControl.Resources>
......
<ListView
            Name="lvUsers"
            Grid.Column="1"
            ItemsSource="{Binding Source={StaticResource GroupedItems}}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <StackPanel Orientation="Horizontal">
                            <Rectangle
                                Name="Mod"
                                Width="24"
                                Height="24"
                                Fill="Black">
                                <Rectangle.OpacityMask>
                                    <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_crown}" />
                                </Rectangle.OpacityMask>
                                <Rectangle.Style>
                                    <Style TargetType="Rectangle">
                                        <Setter Property="Visibility" Value="Hidden" />
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=IsMod, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
                                                <Setter Property="Visibility" Value="Visible" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Rectangle.Style>
                            </Rectangle>
                            <Rectangle
                                Name="Sub"
                                Width="24"
                                Height="24"
                                Fill="Black">
                                <Rectangle.OpacityMask>
                                    <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_heart}" />
                                </Rectangle.OpacityMask>
                                <Rectangle.Style>
                                    <Style TargetType="Rectangle">
                                        <Setter Property="Visibility" Value="Hidden" />
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=IsSub}" Value="True">
                                                <Setter Property="Visibility" Value="Visible" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Rectangle.Style>
                            </Rectangle>
                            <TextBlock
                                Margin="10,0,0,0"
                                VerticalAlignment="Center"
                                FontWeight="Bold"
                                Text="{Binding Path=Name}" />
                        </StackPanel>
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <Expander
                                            Background="Transparent"
                                            BorderThickness="0"
                                            DataContext="{Binding Items}"
                                            Foreground="Transparent"
                                            IsExpanded="True">
                                            <Expander.Header>
                                                <StackPanel Orientation="Horizontal">
                                                    <TextBlock
                                                        VerticalAlignment="Top"
                                                        FontSize="22"
                                                        FontWeight="Bold"
                                                        Foreground="Gray"
                                                        Text="{Binding Type}" />
                                                </StackPanel>
                                            </Expander.Header>
                                            <ItemsPresenter />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
            <ListView.ContextMenu>
                <ContextMenu Name="ViewerContextMenu">
                    <MenuItem Command="{Binding MuteCommand}" Header="Mute Viewer" />
                    <MenuItem Command="{Binding UnmuteCommand}" Header="Unmute Viewer" />
                    <MenuItem Command="{Binding ModCommand}" Header="Mod Viewer" />
                    <MenuItem Command="{Binding UnmodCommand}" Header="Unmod Viewer" />
                    <MenuItem Command="{Binding ShowUserInfo}" Header="User Information" />
                </ContextMenu>
            </ListView.ContextMenu>
        </ListView>

Model:

[PropertyChanged.ImplementPropertyChanged]
        public class Viewers {
            public bool IsMod { get; set; }
            public bool IsSub { get; set; }
            public string Name { get; set; }
            public string TwitchID { get; set; }
            public SortDirectionListView Type { get; set; }
        }

        public enum SortDirectionListView {
            Admin,
            Mod,
            Subscriber,
            Follower,
            Viewer
        }

My ViewModel just contains the collection with the viewers.

public ObservableCollection<Models.Chat.Viewers> Viewers { get; set; }

Now my problem: In the debugger I can see two viewers and both have diffrent "Types":enter image description here

But both shows up as "Mod". Not as a Viewer:enter image description here

I don't see any difference between my test application and my real application and I don't know why the first one works, but not the second one.

Maybe I missed something? Thanks for reading!

like image 452
Mojack Avatar asked Jun 08 '26 20:06

Mojack


1 Answers

I have finally found a solution for my problem. The problem: In my example i add the items before the listview will be 'draw'.

In my real application the users will only add to the list from an event. So i have to tell my application, that i want to refresh my listview.

And there we go, i add to the CollectionViewSource "LiveGroupingProperties".

<CollectionViewSource
        x:Key="cvsViewers"
        IsLiveGroupingRequested="True"
        Source="{Binding ChatHandler.Viewers}">
        <CollectionViewSource.LiveGroupingProperties>
            <clr:String>Type</clr:String>
        </CollectionViewSource.LiveGroupingProperties>
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Type" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
like image 164
Mojack Avatar answered Jun 10 '26 08:06

Mojack



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!