我有一个带有 ListCollectionView 作为数据源的 ItemControl。ItemControl 使用 Expander 控件对项目进行分组。当我执行 ListCollectionView.Refresh() 时,展开的 Expander 控件会折叠。如何使扩展的控件保持扩展状态?
<ItemsControl HorizontalAlignment="Stretch" ItemsSource="{Binding}" Name="ItemsControl1">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type GroupingWithExpander:DataItem}">
<TextBlock Text="{Binding Text}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<Expander BorderThickness="1" BorderBrush="Gray" IsExpanded="{Binding IsExpanded}">
<Expander.Resources>
<GroupingWithExpander:DataGroupToNameConverter x:Key="DataGroupToNameConverter" />
</Expander.Resources>
<Expander.Header>
<TextBlock Text="{Binding Name, Converter={StaticResource DataGroupToNameConverter}}" />
</Expander.Header>
<StackPanel Orientation="Vertical">
<ItemsPresenter Margin="5 0" />
</StackPanel>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBox Name="TextBox1" />
<Button Click="Button_Click">
<Button.Content>
<TextBlock Text="do something" />
</Button.Content>
</Button>
public partial class MainWindow : Window{
public MainWindow()
{
InitializeComponent();
var group1 = new DataGroup {IsExpanded = false, Name = "group #1"};
var group2 = new DataGroup {IsExpanded = true, Name = "group #2"};
const int itemsCount = 6;
DataItem[] dataItems = new DataItem[itemsCount];
for (int i = 0; i < itemsCount; i++)
{
DataItem item = new DataItem
{
Group = (i%2 == 0 ? group1 : group2),
Text = System.IO.Path.GetRandomFileName()
};
dataItems[i] = item;
}
ListCollectionView v = new ListCollectionView(dataItems);
v.GroupDescriptions.Add(new PropertyGroupDescription("Group"));
v.Filter = FilterDataItem;
this.DataContext = v;
}
private bool FilterDataItem(object o)
{
DataItem item = o as DataItem;
return item.Contains(this.TextBox1.Text);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ListCollectionView v = (ListCollectionView) this.DataContext;
v.Refresh();
}
}
class DataGroup : IEquatable<DataGroup>, INotifyPropertyChanged
{
public string Name { get; set; }
private bool _isExpanded;
public bool IsExpanded
{
get { return _isExpanded; }
set
{
_isExpanded = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("IsExpanded"));
}
}
public bool Equals(DataGroup other)
{
return other != null && this.Name == other.Name;
}
public event PropertyChangedEventHandler PropertyChanged;
}
class DataItem
{
public string Text { get; set; }
public DataGroup Group { get; set; }
public virtual bool Contains(string filterString)
{
return Text != null && (string.IsNullOrEmpty(filterString) || Text.Contains(filterString));
}
}
class DataGroupToNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is DataGroup)) throw new ArgumentException("type DataGroup is expected", "value");
DataGroup g = (DataGroup) value;
return g.Name;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}