question

Heiko-6891 avatar image
0 Votes"
Heiko-6891 asked Heiko-6891 edited

Customizing separators in a ListView

Hi,

I want to customize the separators in a ListView. In C# I insert some separator instances into the list. I want to set a different background color and place a TextBlock with different text inside a separator. On Stackoverflow I found how I could do this for Menus and ToolBars, but how can I achieve this for a ListView?


windows-wpfdotnet-wpf-xamldotnet-standard
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

HuiLiu-MSFT avatar image
1 Vote"
HuiLiu-MSFT answered HuiLiu-MSFT commented

You could use the following code to add custom separators in the ListView.
The code of xaml:

 <Window.Resources>
         <Style x:Key="MySeparatorStyle" TargetType="{x:Type Separator}">
             <Setter Property="Focusable" Value="false"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="{x:Type Separator}">
                         <Border  Width="80" 
                         BorderBrush="Black" 
                         BorderThickness="1" 
                         Background="LightGray" 
                         Height="30" 
                         SnapsToDevicePixels="true">
                             <TextBlock Background="AliceBlue" Width="80" Height="30" Text=" separator "/>
                         </Border>
                     </ControlTemplate>
                 </Setter.Value>
             </Setter>
         </Style>
         <DataTemplate x:Key="myCellTemplateName">
             <StackPanel>
                 <TextBlock Background="LightGray" Width="80" HorizontalAlignment="Center" Text="{Binding Name}"/>
                 <TextBlock Background="LightGreen" Width="80" Text="separator"/>
                 <Separator Style="{StaticResource MySeparatorStyle}"/>
             </StackPanel>
         </DataTemplate>
         <DataTemplate x:Key="myCellTemplateEmployeeNumber">
             <StackPanel>
                 <TextBlock Background="LightGray" Width="80" HorizontalAlignment="Center" Text="{Binding EmployeeNumber}"/>
                 <TextBlock Background="LightGreen" Width="80" Text="separator"/>
                 <Separator Style="{StaticResource MySeparatorStyle}"/>
             </StackPanel>
         </DataTemplate>
            
     </Window.Resources>
     <Grid>
         <ListView Name="lv" ItemsSource="{Binding}"  BorderThickness="0">
             <ListView.View>
                 <GridView>
                     <GridViewColumn CellTemplate="{StaticResource myCellTemplateName}"  Header="Name" Width="100"/>
                     <GridViewColumn CellTemplate="{StaticResource myCellTemplateEmployeeNumber}" Header="Employee No." Width="100"/>
                 </GridView>
             </ListView.View>
         </ListView>
 </Grid>

The picture of result:

136560-6.png


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.




6.png (21.0 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I wrote the xaml.cs code in the comments, because I can’t write it in the answer.
The code of xaml.cs:

 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Windows;
 namespace CustomizingSeparatorsInListView
 {
   public partial class MainWindow : Window, INotifyPropertyChanged
   {
     private ObservableCollection<Employee> EmployeeInfoDataSource { get; set; }
     public MainWindow()
     {
       InitializeComponent();
       Init();
       DataContext = this;
       lv.ItemsSource = EmployeeInfoDataSource;
     }
     private void Init()
     {
       EmployeeInfoDataSource = new ObservableCollection<Employee>();
       for (int i = 0; i < 5; i++)
       {
         EmployeeInfoDataSource.Add(new Employee { Name = "name" + i, EmployeeNumber = i });
       }
     }
     public event PropertyChangedEventHandler PropertyChanged;
     protected void OnPropertyChanged(string propertyName)
     {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
   }
   public class Employee
   {
     public string Name { get; set; }
     public int EmployeeNumber { get; set; }
   }
 }

0 Votes 0 ·
Heiko-6891 avatar image
0 Votes"
Heiko-6891 answered Heiko-6891 edited

Thank you for the example HuiLiu.

However, it is necessary that the separator should display text across multiple columns, similar to a grouping text, and it should not be selectable. However, I don't want to use the grouping because it builds up the ListView content many times slower than without grouping, and I sometimes have 1000 or (many) more rows.

I imagine something like this:

136731-separators.png

 ObservableCollection<object> FileList = new ObservableCollection<object>();
    
 void FillListView()
 {
     string lastFolder = null;
    
     foreach (File file in AllFiles)
     {
         if (file.Folder != lastFolder)
         {
             FileList.Add(new FolderSeparator(file.Folder));
             lastFolder = file.Folder;
         }
         FileList.Add(file);
     }
 }



separators.png (27.7 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.