如何使用
ItemsControl
具有
TextBox
筛选数据报列
可以使用
项目控制
并绑定到
DataGrid.Columns
这样地:
<ItemsControl Grid.Row="0" ItemsSource="{Binding Path=Columns, ElementName=dataGrid}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Width="{Binding ActualWidth}">
<TextBox.Resources>
<local:ListIndexToValueConverter x:Key="listIndexToValueConverter"/>
</TextBox.Resources>
<TextBox.Text>
<MultiBinding Converter="{StaticResource listIndexToValueConverter}" UpdateSourceTrigger="PropertyChanged">
<Binding Path="DataContext.Filters" ElementName="userControl"/>
<Binding Path="DisplayIndex"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<DataGrid x:Name="dataGrid" Grid.Row="1" ItemsSource="{Binding Users}">
<DataGrid.Columns>
<DataGridTextColumn DisplayIndex="0" Width="*" Binding="{Binding FirstName}"/>
<DataGridTextColumn DisplayIndex="1" Width="*" Binding="{Binding LastName}"/>
<DataGridTextColumn DisplayIndex="2" Width="*" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>
因为你设置了
ItemsControl.ItemsSource
到
数据报列
而不是
DataContext.Filters
你必须设置
DataGridColumn.DisplayIndex
使用
IMultiValueConverter
能够访问
数据上下文筛选器
再一次:
public class ListIndexToValueConverter : IMultiValueConverter
{
private IList _list;
private int _index;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length < 2)
return Binding.DoNothing;
if (values[0] is IList && values[1] is int)
{
_list = (IList)values[0];
_index = (int)values[1];
return _list[_index];
}
return Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
_list[_index] = value;
return new object[] { Binding.DoNothing, Binding.DoNothing };
}
}
ViewModel:
public class UsersViewModel : BindableBase
{
public ObservableCollection<User> Users { get; set; }
private ICollectionView _usersView;
public ObservableCollection<string> Filters { get; set; }
public UsersViewModel()
{
_usersView = CollectionViewSource.GetDefaultView(Users);
_usersView.Filter = delegate (object item)
{
User user = item as User;
List<string> columns = new List<string>() { user.FirstName, user.LastName, user.Age };
bool include = true;
for (int i = 0; i < columns.Count; ++i)
{
if (!string.IsNullOrEmpty(Filters[i]) && columns[i].IndexOf(Filters[i], StringComparison.OrdinalIgnoreCase) == -1)
{
include = false;
break;
}
}
return include;
};
Filters.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => _usersView.Refresh();
}
}