私は同じ問題を持っていた、そしてそれは私に頭痛の多くを与えました。最後に、私はこれに来ました。おそらくもっともエレガントではありませんが、実用的なソリューションです(私はマルチグループ化でも機能させる必要があったので、その機能を無償で利用できます:)。 主なアイデアは、ソートが行われる前に各エクスパンダの状態を覚えておいて、ソートが完了した後に復元することです。これを達成するために私がしました:すべてのマニュアルで
は(実際に私が展開パンダのちょうど状態を保つ)その状態を記録する拡張または崩壊します。エクスパンダの識別子として使用しています)
エクスパンダの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