简体   繁体   中英

ListView with column sorting in WPF

This is actually a generic ListView that will be visible in many parts of the application for different data (I don't know which data it will contain and how many columns it will have), now it works perfectly, but the user should be able to sort each column by clicking on the header of the ListView control, and I don't know how to add that sorting functionality.

This is the XAML code:

<entityList:EntityList 
    Name="EntityList"
    BorderBrush="DarkSlateBlue"
    Visibility="{Binding IsResultsGridVisible, Converter={x:Static converters:BoolToVisibility.Instance}}"                                        
    ItemsSource="{Binding SearchEntities}"                           
    Style="{StaticResource EntityListStyle}"
    ItemsNumber="50"
    View="{Binding ColumnConfig, Converter={ x:Static converters:ConfigToGridViewConverter.Instance}}">
</entityList:EntityList>

And this is the C# code:

internal class ConfigToGridViewConverter : IValueConverter
{
    public static readonly ConfigToGridViewConverter Instance = new ConfigToGridViewConverter();

    private ConfigToGridViewConverter()
    {
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var config = value as ColumnConfig;
        var gridView = new GridView { AllowsColumnReorder = true };

        if (config == null)
        {
            return gridView;
        }

        foreach (var colCfg in config.Columns)
        {
            var binding = new Binding(colCfg.DataField);
            switch (colCfg.Type)
            {
                case AttributeType.Enumerated:
                    if (colCfg.CodeListType != null)
                    {
                        binding.Converter = CodeListIdToDisplayNameConverter.Instance;
                        binding.ConverterParameter = colCfg.CodeListType.Value;
                    }

                    break;

                case AttributeType.Boolean:
                    binding.Converter = BooleanWithUndefinedToLocalisedStringConverter.Instance;
                    break;

                case AttributeType.Date:
                    binding.Converter = DateToShortLocalisedStringConverter.Instance;
                    break;
            }

            var col = new GridViewColumn
            {
                Header = colCfg.Header, // Column headers will need to be localised either when initializing config or at GridView creation time
                DisplayMemberBinding = binding,

            };

            gridView.Columns.Add(col);
        }

        return gridView;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Any idea how could I do this?

  1. Set a GridViewColumnHeader as shown below :

     <GridViewColumn DisplayMemberBinding="{Binding Address}"> <GridViewColumnHeader Content="Address" Click="GridViewColumnHeader_Click"/> </GridViewColumn> 

    Code-Behind

      private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e) { GridViewColumnHeader colHeader = (GridViewColumnHeader)e.OriginalSource; string colName = colHeader.Content.ToString(); CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(LstView.ItemsSource); view.SortDescriptions.Add(new SortDescription(colName, ListSortDirection.Ascending)); view.Refresh(); } 
  2. Specify a HeaderTemplate so that you can handle MouseDownEvent .

Then you have to use CollectionViewSource .

 private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
 {
     string colName = ((TextBlock)sender).Text.ToString();
     CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(LstView.ItemsSource);
     view.SortDescriptions.Add(new SortDescription(colName, ListSortDirection.Ascending));

     view.Refresh();
 }

Adding columns dynamically :

            GridView view = (GridView)LstView.View;
            GridViewColumnHeader colHeader = new GridViewColumnHeader() { Content = "Name" };
            colHeader.Click += colHeader_Click;
            view.Columns.Add(new GridViewColumn()
            {
                DisplayMemberBinding = new Binding("Name"),
                Header = colHeader
            });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM