创建您自己的控件 - GroupExpander - 从 Expander 子类化它
使用以下辅助方法查找可视层次结构中的任何父项:
public static IEnumerable<T> RecurseParents<T>(this DependencyObject child)
{
if (child is T)
{
yield return Get<T>(child);
}
if (child != null)
{
foreach (var parent in RecurseParents<T>(child.GetParentObject()))
{
yield return parent;
}
}
}
public static DependencyObject GetParentObject(this DependencyObject child)
{
if (child == null) return null;
// handle content elements separately
var contentElement = child as ContentElement;
if (contentElement != null)
{
var parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
var fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
// also try searching for parent in framework elements (such as DockPanel, etc)
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null)
{
var parent = frameworkElement.Parent;
if (parent != null) return parent;
}
// if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
现在通过查找父扩展器并计算这是哪个扩展器来编写查找 GroupExpander 级别的逻辑
你可以从下面的代码中得到这个想法:
public class DataGridGroupExpander : GroupExpander
{
#region Class level variables
private bool mSettingIsExpanded = false;
#endregion
#region Constructors
public DataGridGroupExpander()
{
SetBinding(HeaderProperty, new Binding("Name"));
Loaded += DataGridGroupExpander_Loaded;
}
#endregion
#region Properties
#region Owner
private DataGrid mOwner = null;
public DataGrid Owner
{
get { return mOwner; }
private set
{
if (mOwner != value)
{
if (mOwner != null)
{
DetachOwner();
}
mOwner = value;
if (mOwner != null)
{
AttachOwner();
}
}
}
}
private void AttachOwner()
{
SetFieldName();
}
private void DetachOwner()
{
}
#endregion
#region ParentExpander
private DataGridGroupExpander mParentExpander = null;
public DataGridGroupExpander ParentExpander
{
get { return mParentExpander; }
private set
{
if (mParentExpander != value)
{
if (mParentExpander != null)
{
DetachParentExpander();
}
mParentExpander = value;
if (mParentExpander != null)
{
AttachParentExpander();
}
}
}
}
private void AttachParentExpander()
{
SetBinding(ParentExpanderLevelProperty, new Binding("Level") { Source = ParentExpander });
}
private void DetachParentExpander()
{
ClearValue(ParentExpanderLevelProperty);
}
#endregion
#endregion
#region Event handlers
private void DataGridGroupExpander_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
ParentExpander = this.RecurseParents<DataGridGroupExpander>().Skip(1).Take(20).FirstOrDefault();
Owner = this.RecurseParents<DataGrid>().FirstOrDefault();
LoadGroupIsExpandedState();
}
#endregion
#region Methods
private void LoadGroupIsExpandedState()
{
if (!mSettingIsExpanded && Owner != null)
{
mSettingIsExpanded = true;
try
{
IsExpanded = Owner.LoadGroupIsExpandedState(Header);
}
finally
{
mSettingIsExpanded = false;
}
}
}
private void PersistGroupIsExpandedState()
{
if (!mSettingIsExpanded && Owner != null)
{
Owner.PersistGroupIsExpandedState(Header, IsExpanded);
}
}
private void SetFieldName()
{
var fieldName = "";
if (Owner != null && Owner.Items != null && Owner.Items.GroupDescriptions.Count > Level)
{
var groupDescription = Owner.Items.GroupDescriptions[Level] as PropertyGroupDescription;
if(groupDescription!=null)
{
fieldName = groupDescription.PropertyName;
}
}
SetValue(FieldNameKey, fieldName);
}
#endregion
#region Overrides
tected override void HeaderUpdated()
{
LoadGroupIsExpandedState();
}
tected override void IsExpandedUpdated()
{
PersistGroupIsExpandedState();
}
#endregion
#region Dependency Properties
#region ParentExpanderLevel
public int ParentExpanderLevel
{
get { return (int)GetValue(ParentExpanderLevelProperty); }
set { SetValue(ParentExpanderLevelProperty, value); }
}
public static readonly System.Windows.DependencyProperty ParentExpanderLevelProperty =
System.Windows.DependencyProperty.Register(
"ParentExpanderLevel",
typeof(int),
typeof(DataGridGroupExpander),
new System.Windows.PropertyMetadata(-1, OnParentExpanderLevelPropertyChanged));
private static void OnParentExpanderLevelPropertyChanged(System.Windows.DependencyObject sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
var control = sender as DataGridGroupExpander;
if (control != null)
{
control.ParentExpanderLevelUpdated();
}
}
private void ParentExpanderLevelUpdated()
{
SetValue(LevelKey, ParentExpanderLevel + 1);
}
#endregion
#region Level
public int Level
{
get { return (int)GetValue(LevelProperty); }
}
internal static readonly DependencyPropertyKey LevelKey = DependencyProperty.RegisterReadOnly(
"Level",
typeof(int),
typeof(DataGridGroupExpander),
new System.Windows.PropertyMetadata(0, OnLevelPropertyChanged));
public static readonly DependencyProperty LevelProperty = LevelKey.DependencyProperty;
private static void OnLevelPropertyChanged(System.Windows.DependencyObject sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
var control = sender as DataGridGroupExpander;
if (control != null)
{
control.LevelUpdated();
}
}
private void LevelUpdated()
{
SetFieldName();
}
#endregion
#region FieldName
public string FieldName
{
get { return (string)GetValue(FieldNameProperty); }
}
internal static readonly DependencyPropertyKey FieldNameKey = DependencyProperty.RegisterReadOnly(
"FieldName",
typeof(string),
typeof(DataGridGroupExpander),
new PropertyMetadata(null, OnFieldNamePropertyChanged));
public static readonly DependencyProperty FieldNameProperty = FieldNameKey.DependencyProperty;
private static void OnFieldNamePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as DataGridGroupExpander;
if (control != null)
{
control.FieldNameUpdated();
}
}
private void FieldNameUpdated()
{
}
#endregion
#endregion
}