开发者

wpf set sorting programmatically, so that the header is toggled as sorted

I have a problem with a wpf toolkit DataGrid.

I have an ItemsSource with three columns:

FirstName

LastName

Address

In the C# codebehind I set the sort direction and which column to sort on like this:

ICollectionView view = CollectionViewSource.GetDefaultView(dataG开发者_开发问答rid1.ItemsSource);
view.SortDescriptions.Clear();
view.SortDescriptions.Add(new SortDescription("LastName", ListSortDirection.Ascending));
view.Refresh();

There is no problem in the actual sorting but there is in the headers visual style. If the user sorts a column by clicking on the header, the visual style changes, but the visual style does not indicate that the column sort description is set programmatically.

Why is this, and how can I toggle the header so it will show up as sorted?


I haven't tried it before, but I would think you could set the SortDirection property of the column.

            int columnIndex = 0;
            this.dataGrid1.ColumnFromDisplayIndex(columnIndex).SortDirection = 
                ListSortDirection.Descending;


Below sample will let you sort the data grid using the comboboxes as well as clicking directly on the datagrid.

XAML:

<Window x:Class="DataGridDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=System"
    Height="300" Width="300">

    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues" 
            ObjectType="{x:Type System:Enum}" 
            x:Key="SortDirections">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="ComponentModel:ListSortDirection" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>

    <StackPanel>
        <ComboBox 
            Name="_columnsComboBox"
            ItemsSource="{Binding Path=Columns, ElementName=_dataGrid}" 
            DisplayMemberPath="Header"
            SelectionChanged="OnSort" />
        <ComboBox 
            Name="_sortDirectionsComboBox"
            ItemsSource="{Binding Source={StaticResource SortDirections}}" 
            SelectionChanged="OnSort" />
        <Controls:DataGrid 
            Name="_dataGrid"
            ItemsSource="{Binding Path=PeopleData}" />

    </StackPanel>
</Window>

Code behind:

using System;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.Windows.Controls;

namespace DataGridDemo
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            PeopleData = new DataTable();
            PeopleData.Columns.Add(new DataColumn("Name", typeof(string)));
            PeopleData.Columns.Add(new DataColumn("Age", typeof(int)));

            var row = PeopleData.NewRow();
            row["Name"] = "Sara";
            row["Age"] = 25;
            PeopleData.Rows.Add(row);

            row = PeopleData.NewRow();
            row["Name"] = "Bob";
            row["Age"] = 37;
            PeopleData.Rows.Add(row);

            row = PeopleData.NewRow();
            row["Name"] = "Joe";
            row["Age"] = 10;
            PeopleData.Rows.Add(row);

            DataContext = this;
        }

        public DataTable PeopleData { get; private set;}

        private void OnSort(object sender, SelectionChangedEventArgs e)
        {
            if (_sortDirectionsComboBox.SelectedIndex == -1 || _columnsComboBox.SelectedIndex == -1)
            {
                return;
            }

            foreach (DataGridColumn dataColumn in _dataGrid.Columns)
            {
                dataColumn.SortDirection = null;
            }

            ListSortDirection sortDescription = (ListSortDirection)(_sortDirectionsComboBox.SelectedItem);
            DataGridColumn selectedDataColumn = _columnsComboBox.SelectedItem as DataGridColumn;
            selectedDataColumn.SortDirection = sortDescription;

            ICollectionView view = CollectionViewSource.GetDefaultView(_dataGrid.ItemsSource);
            view.SortDescriptions.Clear();
            view.SortDescriptions.Add(new SortDescription(selectedDataColumn.Header as string, sortDescription));
            view.Refresh();
        }
    }
}


If you want to synchronize the effective sort to Visual style on column, this should help:

  ( (INotifyCollectionChanged)Items.SortDescriptions ).CollectionChanged += new NotifyCollectionChangedEventHandler( OnItemsSortDescriptionsChanged );


 private void OnItemsSortDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e )
    {
        //Synchronize effective sorting in the grid and Visual style on columns
        if ( Items != null )
        {
            foreach ( DataGridColumn column in Columns )
            {
                column.SortDirection = null;

                foreach ( SortDescription sd in Items.SortDescriptions )
                {
                    if ( column.SortMemberPath == sd.PropertyName )
                    {
                        column.SortDirection = sd.Direction;
                        break;
                    }
                }
            }
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜