2012-03-28 7 views
1

私は特定のプロパティでデータをグループ化しているWPFデータグリッドを持っています。 すべての標準的なもの。 しかし、列ヘッダーの1つをクリックしてその列で並べ替えると、すべてのグループが折りたたまれます。可能であれば、これを防止したいと思います。 DataGridのSortingイベントをトラップできます。グループのExpanderを "IsExpanded"に設定しようとすると、展開されていないのに、IsExpandedが既にtrueのように見えるため、何の効果もありません。ソートでデータグリッドグループが折りたたまれないようにしますか?

私のデータだけではなく、標準的な動作であるように見えるので、これを達成する方法について誰かが与えることができる例があります。

私はデータグリッドのために持っているXAMLのようなある:

<DataGrid ItemsSource="{Binding Items}" x:Name="dataGrid"> 
    <DataGrid.GroupStyle> 
     <GroupStyle> 
      <GroupStyle.ContainerStyle> 
       <Style TargetType="GroupItem"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate> 
           <Expander> 
            <Expander.Header> 
             <TextBlock> 
            <TextBlock.Text> 
             <MultiBinding StringFormat="{}{0} ({1} Items)"> 
              <MultiBinding.Bindings> 
               <Binding Path="Name"/> 
               <Binding Path="ItemCount"/> 
              </MultiBinding.Bindings> 
             </MultiBinding> 
            </TextBlock.Text> 
             </TextBlock> 
            </Expander.Header> 
            <ItemsPresenter/> 
           </Expander> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </GroupStyle.ContainerStyle> 
     </GroupStyle> 
    </DataGrid.GroupStyle> 
</DataGrid> 

おかげ

答えて

4

私は同じ問題を持っていた、そしてそれは私に頭痛の多くを与えました。最後に、私はこれに来ました。おそらくもっともエレガントではありませんが、実用的なソリューションです(私はマルチグループ化でも機能させる必要があったので、その機能を無償で利用できます:)。 主なアイデアは、ソートが行われる前に各エクスパンダの状態を覚えておいて、ソートが完了した後に復元することです。これを達成するために私がしました:すべてのマニュアルで

  1. は(実際に私が展開パンダのちょうど状態を保つ)その状態を記録する拡張または崩壊します。エクスパンダの識別子として使用しています)

  2. エクスパンダのIsExpandedプロパティの評価時に、現在のエクスパンダの状態が保存された状態のリストにあるかどうかをチェックし、それに応じてIsExpandedの値を返します。 GroupStyleで

エキスパンダー:

<Expander x:Name="exp" Expanded="exp_Expanded" Collapsed="exp_Collapsed" > 
     <Expander.IsExpanded> 
      <MultiBinding Converter="{StaticResource ResourceKey=expanderStateConverter}" Mode="OneWay" > 
       <Binding Mode="OneWay"/> 
       <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="ExpandersStates" /> 
      </MultiBinding> 
     </Expander.IsExpanded> 
    <!-- ... the rest of the boring expander code --> 
    </Expander> 

neccessary場合、コントロールのあなたのタイプとAncestorTypeウィンドウの一部を置換...

ビューのコード:

public List<string> ExpandersStates {get; set; } 
    private void exp_Expanded(object sender, RoutedEventArgs e) 
    { 
     ExpandCollapseExpander(sender as Expander, e, true); 
    } 

    private void exp_Collapsed(object sender, RoutedEventArgs e) 
    { 
     ExpandCollapseExpander(sender as Expander, e, false); 
    } 

    private void ExpandCollapseExpander(Expander exp, RoutedEventArgs e, bool doExpand) 
    { 
     CollectionViewGroup collectionViewGroup = exp.DataContext as CollectionViewGroup; 
     if (collectionViewGroup == null) 
     { 
      return; 
     } 
     string viewGroupId = FormViewGroupIdentifier(collectionViewGroup, null); 
     if (doExpand) 
     { 
      if (!ExpandersStates.Contains(viewGroupId)) 
      { 
       ExpandersStates.Add(viewGroupId); 
      } 
     } 
     else 
     { 
      ExpandersStates.Remove(viewGroupId); 
     } 
     e.Handled = true; 
    } 

    public static string FormViewGroupIdentifier(CollectionViewGroup collectionViewGroup, string sufix) 
    { 
     string formViewGroupIdentifier = collectionViewGroup.Name + sufix; 
     CollectionViewGroup parentgroup = GetParent(collectionViewGroup); 
     if (parentgroup == null) 
     { 
      return formViewGroupIdentifier; 
     } 
     else 
     { 
      return FormViewGroupIdentifier(parentgroup, "putHereSomeDelimiterWhichWillNeverOccurInYourGroupingProperty" + formViewGroupIdentifier); 
     } 
    } 

    private static CollectionViewGroup GetParent(CollectionViewGroup collectionViewGroup) 
    { 
     Type type = collectionViewGroup.GetType(); 
     if (type.Name == "CollectionViewGroupRoot") 
     {//if we are at the root level return null as there is no parent 
      return null; 
     } 

     CollectionViewGroup parentgroup 
      = type.GetProperty("Parent", System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) 
      .GetValue(collectionViewGroup, null) as CollectionViewGroup; 
     return parentgroup; 
    } 

コンバータ:

public class ExpanderStateConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     CollectionViewGroup collectionViewGroup = values[0] as CollectionViewGroup; 
     List<string> expandersStates = values[1] as List<string>; 
     if (!expandersStates.Any()) 
     {//prevent forming group identifier to speed up process as there are no expanded expanders anyway 
      return false; 
     } 

     string groupId = MainWindow.FormViewGroupIdentifier(collectionViewGroup, null); 
     bool contains = expandersStates.Contains(groupId); 
     return contains; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     return new object[2]; 
    } 
} 

ここで任意の区切り記号を使用してエクスパンダの識別子を生成することはベストプラクティスではないことを認識しており、これを改善する方法についての提案があります。

ここにあり全コード:<Expander IsExpanded="True">を:ExpandersForSO2

0

は、あなたは、単に追加することにより、<Expander>ノードを変更できませんでしたか?