如何调用Items.Refresh()?
How to call Items.Refresh()?
我正在为一个集合制作过滤器。
我知道如何使用 CollectionViewSource 来做到这一点。
但我想在不使用 CVS 的情况下完成它。
按照我的思路,ItemsControl.Items属性里面有个CollectionView,可以用这个属性.
的方法
可以毫无问题地添加过滤器。
但是在调用 Items.Refresh() 之后没有任何变化。
简单示例:
<UniformGrid Columns="2">
<FrameworkElement.Resources>
<sc:StringCollection
x:Key="coll">
<sys:String>112</sys:String>
<sys:String>22</sys:String>
<sys:String>33</sys:String>
<sys:String>114</sys:String>
<sys:String>411</sys:String>
</sc:StringCollection>
<CollectionViewSource
x:Key="cvs"
Source="{Binding Mode=OneWay, Source={StaticResource coll}}"
Filter="OnFilterCV"/>
</FrameworkElement.Resources>
<TextBox x:Name="tBox"
Text="1"
TextChanged="OnTextChanged"
VerticalAlignment="Center"/>
<TextBox x:Name="tBoxCV"
Text="1"
TextChanged="OnTextChangedCV"
VerticalAlignment="Center"/>
<ItemsControl x:Name="iCtrl"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource coll}}">
</ItemsControl>
<ItemsControl x:Name="iCtrlCV"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource cvs}}">
</ItemsControl>
</UniformGrid>
public partial class MainWindow : Window
{
private readonly CollectionViewSource cvs;
public MainWindow()
{
InitializeComponent();
iCtrl.Items.Filter = OnFilter;
cvs = (CollectionViewSource)iCtrlCV.FindResource("cvs");
}
private bool OnFilter(object obj)
{
if (string.IsNullOrWhiteSpace(tBox.Text))
return true;
string item = (string)obj;
return item.Contains(tBox.Text, StringComparison.OrdinalIgnoreCase);
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
Debug.WriteLine($"OnTextChanged:\"{tBox.Text}\"");
iCtrl?.Items.Refresh();
}
private void OnFilterCV(object sender, FilterEventArgs e)
{
e.Accepted = string.IsNullOrWhiteSpace(tBoxCV.Text) ||
((string)e.Item).Contains(tBoxCV.Text, StringComparison.OrdinalIgnoreCase);
}
private void OnTextChangedCV(object sender, TextChangedEventArgs e)
{
Debug.WriteLine($"OnTextChangedCV:\"{tBoxCV.Text}\"");
cvs?.View.Refresh();
}
}
我是误会了什么还是做错了什么?
已更新。
解决方案基于@BionicCode 的评论。
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
Debug.WriteLine($"OnTextChanged:\"{tBox.Text}\"");
//iCtrl?.Items.Refresh();
if (iCtrl != null)
iCtrl.Items.Filter = new Predicate<object>(OnFilter);
}
ItemsControl.Items
的类型为 ItemsCollection
。 ItemsCollection
实现了不同的 Refresh
行为。 Items
属性 基本上供内部使用。如果你必须依赖 CollectionView.Refresh
,你应该明确地使用 CollectionView
:
ItemsControl itemsControl;
itemsControl.Items.Filter = item => (item as string).Contains("A");
CollectionView collectionView = CollectionViewSource.GetDefaultView(itemsControl.ItemsSource);
collectionView.Refresh();
我正在为一个集合制作过滤器。
我知道如何使用 CollectionViewSource 来做到这一点。
但我想在不使用 CVS 的情况下完成它。
按照我的思路,ItemsControl.Items属性里面有个CollectionView,可以用这个属性.
的方法
可以毫无问题地添加过滤器。
但是在调用 Items.Refresh() 之后没有任何变化。
简单示例:
<UniformGrid Columns="2">
<FrameworkElement.Resources>
<sc:StringCollection
x:Key="coll">
<sys:String>112</sys:String>
<sys:String>22</sys:String>
<sys:String>33</sys:String>
<sys:String>114</sys:String>
<sys:String>411</sys:String>
</sc:StringCollection>
<CollectionViewSource
x:Key="cvs"
Source="{Binding Mode=OneWay, Source={StaticResource coll}}"
Filter="OnFilterCV"/>
</FrameworkElement.Resources>
<TextBox x:Name="tBox"
Text="1"
TextChanged="OnTextChanged"
VerticalAlignment="Center"/>
<TextBox x:Name="tBoxCV"
Text="1"
TextChanged="OnTextChangedCV"
VerticalAlignment="Center"/>
<ItemsControl x:Name="iCtrl"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource coll}}">
</ItemsControl>
<ItemsControl x:Name="iCtrlCV"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource cvs}}">
</ItemsControl>
</UniformGrid>
public partial class MainWindow : Window
{
private readonly CollectionViewSource cvs;
public MainWindow()
{
InitializeComponent();
iCtrl.Items.Filter = OnFilter;
cvs = (CollectionViewSource)iCtrlCV.FindResource("cvs");
}
private bool OnFilter(object obj)
{
if (string.IsNullOrWhiteSpace(tBox.Text))
return true;
string item = (string)obj;
return item.Contains(tBox.Text, StringComparison.OrdinalIgnoreCase);
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
Debug.WriteLine($"OnTextChanged:\"{tBox.Text}\"");
iCtrl?.Items.Refresh();
}
private void OnFilterCV(object sender, FilterEventArgs e)
{
e.Accepted = string.IsNullOrWhiteSpace(tBoxCV.Text) ||
((string)e.Item).Contains(tBoxCV.Text, StringComparison.OrdinalIgnoreCase);
}
private void OnTextChangedCV(object sender, TextChangedEventArgs e)
{
Debug.WriteLine($"OnTextChangedCV:\"{tBoxCV.Text}\"");
cvs?.View.Refresh();
}
}
我是误会了什么还是做错了什么?
已更新。 解决方案基于@BionicCode 的评论。
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
Debug.WriteLine($"OnTextChanged:\"{tBox.Text}\"");
//iCtrl?.Items.Refresh();
if (iCtrl != null)
iCtrl.Items.Filter = new Predicate<object>(OnFilter);
}
ItemsControl.Items
的类型为 ItemsCollection
。 ItemsCollection
实现了不同的 Refresh
行为。 Items
属性 基本上供内部使用。如果你必须依赖 CollectionView.Refresh
,你应该明确地使用 CollectionView
:
ItemsControl itemsControl;
itemsControl.Items.Filter = item => (item as string).Contains("A");
CollectionView collectionView = CollectionViewSource.GetDefaultView(itemsControl.ItemsSource);
collectionView.Refresh();