Hol*_*dam 16 c# data-binding wpf xaml
我有一个非常棘手的问题:
我正在使用ListView控件,其ItemsSource设置为CollectionViewSource,包括PropertyGroupDescription以对ListView元素进行分组.CollectionViewSource看起来像这样:
<CollectionViewSource x:Key="ListViewObjects">
<CollectionViewSource.Source>
<Binding Path="CurrentListViewData"/>
</CollectionViewSource.Source>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ObjectType" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
Run Code Online (Sandbox Code Playgroud)
在ListView中,我使用自定义组头,如下所示:
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<DockPanel>
<TextBlock Text="{Binding Path=Items[0].ObjectType />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
Run Code Online (Sandbox Code Playgroud)
如您所见,Expander的IsExpanded属性设置为true.这意味着每当刷新ListView时,都会扩展所有Expander控件.
但是我想保存每个Expander的最后状态.我无法找到一种方法来保存每个ObjectType的Expander状态列表.我正在尝试使用绑定的HashTable和Converter,但是我没有将ObjectType作为ConverterParameter提供,因为它总是作为字符串传递.但这可能不是解决方案.
有人可以给我一个解决方案的提示或想法吗?:)
aKz*_*enT 16
接受的答案是错误的,如评论中所述.我写了以下行为,实现了所需的功能:
public class PersistGroupExpandedStateBehavior : Behavior<Expander>
{
#region Static Fields
public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register(
"GroupName",
typeof(object),
typeof(PersistGroupExpandedStateBehavior),
new PropertyMetadata(default(object)));
private static readonly DependencyProperty ExpandedStateStoreProperty =
DependencyProperty.RegisterAttached(
"ExpandedStateStore",
typeof(IDictionary<object, bool>),
typeof(PersistGroupExpandedStateBehavior),
new PropertyMetadata(default(IDictionary<object, bool>)));
#endregion
#region Public Properties
public object GroupName
{
get
{
return (object)this.GetValue(GroupNameProperty);
}
set
{
this.SetValue(GroupNameProperty, value);
}
}
#endregion
#region Methods
protected override void OnAttached()
{
base.OnAttached();
bool? expanded = this.GetExpandedState();
if (expanded != null)
{
this.AssociatedObject.IsExpanded = expanded.Value;
}
this.AssociatedObject.Expanded += this.OnExpanded;
this.AssociatedObject.Collapsed += this.OnCollapsed;
}
protected override void OnDetaching()
{
this.AssociatedObject.Expanded -= this.OnExpanded;
this.AssociatedObject.Collapsed -= this.OnCollapsed;
base.OnDetaching();
}
private ItemsControl FindItemsControl()
{
DependencyObject current = this.AssociatedObject;
while (current != null && !(current is ItemsControl))
{
current = VisualTreeHelper.GetParent(current);
}
if (current == null)
{
return null;
}
return current as ItemsControl;
}
private bool? GetExpandedState()
{
var dict = this.GetExpandedStateStore();
if (!dict.ContainsKey(this.GroupName))
{
return null;
}
return dict[this.GroupName];
}
private IDictionary<object, bool> GetExpandedStateStore()
{
ItemsControl itemsControl = this.FindItemsControl();
if (itemsControl == null)
{
throw new Exception(
"Behavior needs to be attached to an Expander that is contained inside an ItemsControl");
}
var dict = (IDictionary<object, bool>)itemsControl.GetValue(ExpandedStateStoreProperty);
if (dict == null)
{
dict = new Dictionary<object, bool>();
itemsControl.SetValue(ExpandedStateStoreProperty, dict);
}
return dict;
}
private void OnCollapsed(object sender, RoutedEventArgs e)
{
this.SetExpanded(false);
}
private void OnExpanded(object sender, RoutedEventArgs e)
{
this.SetExpanded(true);
}
private void SetExpanded(bool expanded)
{
var dict = this.GetExpandedStateStore();
dict[this.GroupName] = expanded;
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
它附加一个字典到包含ItemsControl,它保存每个组项的展开状态.这将是持久的,即使控件中的项目发生更改.
用法:
<Expander>
<i:Interaction.Behaviors>
<behaviors:PersistGroupExpandedStateBehavior GroupName="{Binding Name}" />
</i:Interaction.Behaviors>
...
</Expander>
Run Code Online (Sandbox Code Playgroud)
您可以使用Dictionary创建一个新类(比如,ObjectType作为bool值的键),并为其提供一个索引器:
Dictionary<ObjectType, bool> expandStates = new Dictionary<ObjectType, bool>();
public bool this[ObjectType key]
{
get
{
if (!expandStates.ContainsKey(key)) return false;
return expandStates[key];
}
set
{
expandStates[key] = value;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在某个地方的ResourceDictionary中实例化它并将IsExpanded绑定到它,如下所示:
<Expander IsExpanded="{Binding Source={StaticResource myExpMgr}, Path=[Items[0].ObjectType]}">
Run Code Online (Sandbox Code Playgroud)
这可能会做得很好:让WPF调用代码并在需要时传递参数的好方法.(WPF允许你将索引器中的子表达式放在绑定路径中对我来说是新闻 - 虽然不是很好!)
| 归档时间: |
|
| 查看次数: |
4173 次 |
| 最近记录: |