我有同樣的問題,它給了我很多頭疼的。最後,我想到了這一點,可能不是最優雅的,但工作的解決方案(我不得不使它與多組合作,所以你會得到免費的功能:)。 主要思想是在排序發生前記住每個膨脹機的狀態,並在排序完成後恢復。爲了實現這一點,我已經:
在每一個手動展開或摺疊記錄它的狀態(實際上我一直只是指出擴展擴展的)。作爲擴展器標識符,我使用從綁定到擴展器的元素生成的標識)
在評估擴展器的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