Display Value as Header for Group (XAML, C#) - c#

I have got ListView
<ListView ItemsSource="{Binding Path=ListUsers}" DockPanel.Dock="Bottom" >
<ListView.View>
<GridView>
<GridViewColumn Header="Position" DisplayMemberBinding="{Binding Position}" />
<GridViewColumn Header="Counter" DisplayMemberBinding="{Binding Counter}" />
</GridView>
</ListView.View>
I have made ListView.GroupStyle:
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ReadTime" FontSize="14" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ReadTime}" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
Into my ctor in ViewModel I did like this:
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(ListUsers);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("ReadTime");
view.GroupDescriptions.Add(groupDescription);
How to now instead of display text "ReadTime" for each group, display value from ReadTime?

How to now instead of display text "ReadTime" for each group, display value from ReadTime?
There is no the value since there is a header per group and a group may contain several values. If you want to display the first value in the group, you can use the Items collection of the group:
<TextBlock Text="{Binding Items[0].ReadTime}" VerticalAlignment="Bottom" />

Related

Cannot Bind Grouping property in ListView

I have an ObservableCollection of items that I want to use to group my ListView, but I just can't bind my Grouping to that item.
That's my little class:
public class Module
{
public string Name { get; set; }
public Module(string name)
{
Name = name;
}
}
ViewModel:
public ObservableCollection<Module> ServerModules
{
get => serverModules;
set
{
if (serverModules == value) { return; }
serverModules = value;
OnPropertyChanged();
}
}
Here my Xaml Code:
<StackPanel Orientation="Vertical">
<ListView ItemsSource="{Binding ServerModules}">
<ListView.View>
<GridView>
<GridViewColumn Header="Property" Width="200"/>
<GridViewColumn Header="Value" Width="200"/>
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontSize="20" FontWeight="Bold" Foreground="DodgerBlue" Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</StackPanel>
The Name Property cannot be resolved.
I also tried using a CollectionViewSource but it's also not working for me:
<CollectionViewSource x:Key="GroupModules" Source="{Binding ServerModules}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Name"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<ListView ItemsSource="{Binding Source={StaticResource GroupModules}}">
Any ideas and help are really appreciated.
Update Solution:
In my Resources section I defined a CollectionViewSource to set a GroupDescription property and a Style for my GroupItem.
<UserControl.Resources>
<CollectionViewSource x:Key="GroupedModules" Source="{Binding ServiceModuleSetViewModel.AllModuleProperties}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ModuleName" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<!-- ListView GroupStyle.ContainerStyle -->
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock Text="{Binding Name}" FontSize="13" Foreground="DodgerBlue" FontWeight="Bold" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
ListView:
<ListView ItemsSource="{Binding Source={StaticResource GroupedModules}}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.GroupStyle>
<GroupStyle/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="local:ModuleProperty">
<TextBlock FontSize="13" Text="{Binding Path=Name}" TextAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Value" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="local:ModuleProperty">
<TextBox FontSize="13" Text="{Binding Path=Value}" TextAlignment="Center"
Width="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
The ListView control has the CollectionViewSource Resource as ItemsSource.
Each GridViewColumn has a CellTemplate to display my data in the columns.
You need to define style for GroupItem or specify GroupStyle.ContainerStyle
Also for GridViewColumn you need to specify DisplayMemberBinding.
<UserControl.Resources>
<!-- ListView GroupStyle.ContainerStyle -->
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock Text="{Binding Name}" Foreground="Gray" FontWeight="Bold" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel Orientation="Vertical">
<ListView ItemsSource="{Binding ServerModules}">
<ListView.GroupStyle>
<GroupStyle/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Property" DisplayMemberBinding="{Binding Property}" Width="200"/>
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}" Width="200"/>
</GridView>
</ListView.View>
</ListView>
</StackPanel>

Gridview Column for each element in a Group of Listview (WPF/C#)

I have an application that show the data grouped by type, each type has your own group with expander. I want to show for each group a gridviewcolumn like the red selection of Image 1 and put on the green space. What is the best way to do this?
EDIT 1
Following my actual XAML file section with listview:
ListView.xaml
<ListView Name="lstResults" Grid.Row="1" IsEnabled="True" Grid.RowSpan="4" DataContext="All" Grid.ColumnSpan="5" Margin="5,5">
<ListView.View>
<GridView>
<GridViewColumn Header="Linha" Width="Auto" DisplayMemberBinding="{Binding LineNumber}" />
<GridViewColumn Header="Fonte" Width="Auto" DisplayMemberBinding="{Binding Source}" />
<GridViewColumn Header="Data" Width="Auto" DisplayMemberBinding="{Binding Time}" />
<GridViewColumn Header="Log" Width="Auto" DisplayMemberBinding="{Binding LineLog}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Items[0].Pattern, StringFormat={} Teste: {0}}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
<Border CornerRadius="10" Padding="1,1,1,1" BorderThickness="1" BorderBrush="Black" Background="Red" Margin="1,0,0,0" >
<TextBlock Text="{Binding Items.Count,StringFormat={} Items: {0}}" Padding="0" VerticalAlignment="Center" Margin="5,1,5,1" FontSize="15" FontWeight="Bold" Foreground="Black"/>
</Border>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
you can add a ListView inside the groupitem. Try below code.
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Items[0].Pattern, StringFormat={} Teste: {0}}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
<Border CornerRadius="10" Padding="1,1,1,1" BorderThickness="1" BorderBrush="Black" Background="Red" Margin="1,0,0,0" >
<TextBlock Text="{Binding Items.Count,StringFormat={} Items: {0}}" Padding="0" VerticalAlignment="Center" Margin="5,1,5,1" FontSize="15" FontWeight="Bold" Foreground="Black"/>
</Border>
</StackPanel>
</Expander.Header>
<ListView ItemsSource="{TemplateBinding Items}">
<ListView.View>
<GridView>
<GridViewColumn Header="Linha" Width="Auto" DisplayMemberBinding="{Binding LineNumber}" />
<GridViewColumn Header="Fonte" Width="Auto" DisplayMemberBinding="{Binding Source}" />
<GridViewColumn Header="Data" Width="Auto" DisplayMemberBinding="{Binding Time}" />
<GridViewColumn Header="Log" Width="Auto" DisplayMemberBinding="{Binding LineLog}" />
</GridView>
</ListView.View>
</ListView>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>

Edit and search item in listview

is there any control like jquery datatable in WPF for searching item from listview or how i can implement efficient search in listvew.
secondly, I have an image and title in listview control. How can I add "edit functionality" to change image Title.
I don't have any clue about it because I'm new in WPF. how I can perform this task. any example or useful code will be helpfull for me.
<ListView Name="lvDataBinding">
<ListView.View>
<GridView >
<GridViewColumn >
<GridViewColumn.CellTemplate>
<DataTemplate >
<StackPanel Margin="20,5,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<Image Margin="15,5,0,0" Style="{StaticResource PopupImageStyle}" HorizontalAlignment="Center" Width="60" ToolTip="{Binding Name}" Height="60" Source="{Binding ImgPath}"></Image>
<TextBlock Visibility="Hidden" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn >
<GridViewColumn.CellTemplate>
<DataTemplate >
<StackPanel Margin="20,5,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding Title}">
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.FontSize" Value="20"></Setter></Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--<GridViewColumn DisplayMemberBinding="{Binding Name}" />-->
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>

WPF Expander Order by GroupItem count

I have a WPF app with search functionality, and data is bind to data grid. i am grouping the data by table name. how can i sort the expander header by descending order. how to show max count group on top.
XAML code.
</DataGrid.Columns>
<DataGrid.GroupStyle>
<!--Default GroupStyle-->
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Padding="3"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander x:Name="exp"
BorderBrush="#FFA4B97F"
BorderThickness="0,0,0,1"
IsExpanded="{Binding Path=Items[0].IsExpanded}">
<Expander.Header>
<DockPanel TextBlock.FontWeight="Bold">
<TextBlock Text="{Binding Name}" Margin="5,0,5,0" Foreground="Blue" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding Path=ItemCount}"/>
<TextBlock Text=" Items )" />
</DockPanel>
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
Sort the databound list in your ViewModel. Order by item count after the list is populated.

c# WPF ListView Displays either Grouping of Data, but not both

I have a bound ListView on a Window and I've setup XAML to do grouping, but when I try to apply it I either get only data or grouping with no data. The XAML is as follows:
<ListView x:Name="lvNav" HorizontalAlignment="Left" Height="100" Margin="331,41,0,0" VerticalAlignment="Top" Width="166">
<ListView.View>
<GridView>
<GridViewColumn Header="Customer" DisplayMemberBinding="{Binding serviceID}" />
<GridViewColumn Header="S/N" DisplayMemberBinding="{Binding machineID}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
</StackPanel>
</Expander.Header>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
The code that loads the data is:
System.Data.Entity.DbSet<srsr> srsrs = _fa.srsrs;
srsrs.Load();
lvNav.ItemsSource = srsrs.Local;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvNav.ItemsSource);
PropertyGroupDescription pgd = new PropertyGroupDescription("stateID");
view.GroupDescriptions.Add(pgd);
I'm assuming I'm missing something relatively simple here, so hopefully someone can point me in the right direction.
If you would use the MVVM approach i.e. without code behind, you could use this:
<CollectionViewSource Source="{Binding PropertyOnYourVM}" x:Key="NameOfTheGrouping">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="PropertyToGroupOn"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
you can then use it like this on your ListView:
<ListView ItemsSource="{Binding Source={StaticResource NameOfTheGrouping}}">
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource YourStyleNameHere}"/>
</ListView.GroupStyle>
But because you are NOT using MVVM you will have to do it in code behind.
BTW: you forgot <ItemsPresenter /> in your xaml, which goes between </Expander.Header> and </Expander>

Categories