2016-03-30 4 views
3

次の列のDataGridがあります。enumという名前のコンバータが付いたTypeにバインドされています。WPFデータグリッドの並べ替えでコンバータの列挙型が失敗する

<DataGridTextColumn Header="Type" 
Binding="{Binding Path=Type,Converter={StaticResource EnumStringConverter}}" /> 

変換された値が正しく表示されます。しかし、それは並べ替えに失敗します。

Ascending sort goes wrong

descending sort goes wrong too!

昇順ソートの正しい順序は、Cash, Debt Security and Goldされ又はソートを降順逆ているべきです。列挙型は

enum SomeType 
{ 
    Cash = 0, 
    Gold = 1, 

    // few more values ... 

    DebtSecurity = 6, 
} 

として定義されて

私も列にSortMemberPath="Type"を使用しようとしましたが、それでも同じ結果を与えています。私はここで何か非常に基本的なものを欠いています

+0

あなたのグリッドは列挙ではなく列挙をソートしています。たぶんコンバータの代わりに、列挙型を文字列に変換して代わりに使用するviewmodelの別のプロパティを作成します。 –

+0

はい、私はなぜそれが起こっているのかについての説明を探していましたか?さらに多くのXAML指向のソリューションを提供します。 – bit

答えて

1

広範な検索を行い、部分的に答えを見つけたら、利用可能な回答をマージして、このような一般的な要件を解決することができます。

したがって、列挙型の変換された値で並べ替えを有効にする場合。

1))

/// <summary> 
/// Allows a grid to be sorted based upon the converted value. 
/// </summary> 
public static class GridEnumSortingBehavior 
{ 
    #region Properties 

    public static readonly DependencyProperty UseBindingToSortProperty = 
     DependencyProperty.RegisterAttached("UseBindingToSort", typeof(bool), typeof(GridEnumSortingBehavior), 
              new PropertyMetadata(UseBindingToSortPropertyChanged)); 

    #endregion 

    public static void SetUseBindingToSort(DependencyObject element, bool value) 
    { 
     element.SetValue(UseBindingToSortProperty, value); 
    } 

    #region Private events 

    private static void UseBindingToSortPropertyChanged(DependencyObject element, DependencyPropertyChangedEventArgs e) 
    { 
     var grid = element as DataGrid; 
     if (grid == null) 
     { 
      return; 
     } 

     var canEnumSort = (bool)e.NewValue; 
     if (canEnumSort) 
     { 
      grid.Sorting += GridSorting; 
     } 
     else 
     { 
      grid.Sorting -= GridSorting; 
     } 
    } 

    private static void GridSorting(object sender, DataGridSortingEventArgs e) 
    { 
     var boundColumn = e.Column as DataGridBoundColumn; 
     if (boundColumn == null) 
     { 
      return; 
     } 

     // Fetch the converter,binding prop path name, if any 
     IValueConverter converter = null; 
     string bindingPropertyPath = null; 
     if (boundColumn.Binding == null) 
     { 
      return; 
     } 
     var binding = boundColumn.Binding as Binding; 
     if (binding == null || binding.Converter == null) 
     { 
      return; 
     } 
     converter = binding.Converter; 
     bindingPropertyPath = binding.Path.Path; 
     if (converter == null || bindingPropertyPath == null) 
     { 
      return; 
     } 

     // Fetch the collection 
     var dataGrid = (DataGrid)sender; 
     var lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(dataGrid.ItemsSource); 
     if (lcv == null || lcv.ItemProperties == null) 
     { 
      return; 
     } 

     // Fetch the property bound to the current column (being sorted) 
     var bindingProperty = lcv.ItemProperties.FirstOrDefault(prop => prop.Name == bindingPropertyPath); 
     if (bindingProperty == null) 
     { 
      return; 
     } 

     // Apply custom sort only for enums types 
     var bindingPropertyType = bindingProperty.PropertyType; 
     if (!bindingPropertyType.IsEnum) 
     { 
      return; 
     } 

     // Apply a custom sort by using a custom comparer for enums 
     e.Handled = true; 
     ListSortDirection directionToSort = boundColumn.SortDirection != ListSortDirection.Ascending 
               ? ListSortDirection.Ascending 
               : ListSortDirection.Descending; 
     boundColumn.SortDirection = directionToSort; 
     lcv.CustomSort = new ConvertedEnumComparer(converter, directionToSort, bindingPropertyType, bindingPropertyPath); 
    } 

    #endregion 
} 

2次conveerted-列挙ソートクラスを追加し、その変換された値

/// <summary> 
/// Converts the value of enums and then compares them 
/// </summary> 
public class ConvertedEnumComparer : IComparer 
{ 

    #region Fields 

    private readonly Type _enumType; 
    private readonly string _enumPropertyPath; 
    private readonly IValueConverter _enumConverter; 
    private readonly ListSortDirection _directionToSort; 

    #endregion 

    public ConvertedEnumComparer(IValueConverter enumConverter, ListSortDirection directionToSort, Type enumType, string enumPropertyPath) 
    { 
     _enumType = enumType; 
     _enumPropertyPath = enumPropertyPath; 
     _enumConverter = enumConverter; 
     _directionToSort = directionToSort; 
    } 

    #region IComparer implementation 

    public int Compare(object parentX, object parentY) 
    { 
     if (!_enumType.IsEnum) 
     { 
      return 0; 
     } 

     // extract enum names from the parent objects 
     var enumX = TypeDescriptor.GetProperties(parentX)[_enumPropertyPath].GetValue(parentX); 
     var enumY = TypeDescriptor.GetProperties(parentY)[_enumPropertyPath].GetValue(parentY); 

     // convert enums 
     object convertedX = _enumConverter.Convert(enumX, typeof(string), null, Thread.CurrentThread.CurrentCulture); 
     object convertedY = _enumConverter.Convert(enumY, typeof(string), null, Thread.CurrentThread.CurrentCulture); 

     // compare the converted enums 
     return _directionToSort == ListSortDirection.Ascending 
           ? Comparer.Default.Compare(convertedX, convertedY) 
           : Comparer.Default.Compare(convertedX, convertedY) * -1; 
    } 

    #endregion 
} 

3に基づいて列挙値を比較するカスタム比較子を追加します。)最後に使用しますこれはどんな場合でもDataGridで、単に振る舞いをTrue

<DataGrid ItemsSource="{Binding YourDataCollectionWithEnumProperty}" 
yourbehaviors:GridEnumSortingBehavior.UseBindingToSort="True" > 
関連する問題