关于ItemsControl中使用不同ItemSource及相关XAML实现的技术问询
在ItemsControl中使用不同ItemSource及XAML代码解析
我来帮你梳理一下如何在ItemsControl中切换不同的ItemSource,同时解析你给出的这段XAML代码:
一、如何在ItemsControl中使用不同的ItemSource
想要给ItemsControl用不同的数据源,常见的几种方式如下:
- 直接绑定不同的集合属性:如果你的ViewModel里有多个集合(比如
FilterItems、ColumnInfos这类),直接修改ItemsSource的绑定路径就行,比如ItemsSource="{Binding FilterItems}"。记得集合最好用ObservableCollection<T>,它实现了INotifyCollectionChanged,增删元素时UI会自动更新。 - 用DataTemplateSelector动态适配:如果不仅要换数据源,还要根据数据类型或者条件切换列表项的模板,可以自定义一个
DataTemplateSelector类,在代码里写判断逻辑,返回对应的模板,然后给ItemsControl的ItemTemplateSelector属性赋值,这样不同的数据源可以对应不同的渲染样式。 - 通过触发器切换绑定:可以在XAML里用
DataTrigger,根据ViewModel的某个开关属性(比如IsShowingFilters),动态改变ItemsSource的绑定路径,比如当IsShowingFilters为True时绑定FilterItems,否则绑定ColumnInfos。
二、你的XAML代码解析
首先先把你截断的代码补全(通常这类交互行为是调用ViewModel的命令),完整代码大概是这样:
<ItemsControl ItemsSource="{Binding Vwr.Table.Vals, UpdateSourceTrigger=PropertyChanged}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock x:Name="SearchCol" Text="{Binding Col}" Style="{StaticResource tabTextBlock}"/> <TextBox x:Name="SearchText" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200"> <i:Interaction.Triggers> <i:EventTrigger EventName="TextChanged"> <i:InvokeCommandAction Command="{Binding DataContext.SearchTextChangedCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/> </i:EventTrigger> </i:Interaction.Triggers> </TextBox> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
逐段解析一下:
ItemsControl核心绑定
ItemsSource="{Binding Vwr.Table.Vals, UpdateSourceTrigger=PropertyChanged}":这里把ItemsControl的数据源绑定到ViewModel里的Vwr.Table.Vals集合。UpdateSourceTrigger=PropertyChanged主要是针对属性值变化的即时更新,不过对于集合来说,更关键的是Vals要是ObservableCollection类型,这样集合里的元素增删时UI才会同步更新。
列表项模板定义
<ItemsControl.ItemTemplate>指定了每个列表项的UI样式,用DataTemplate来描述单个Vals元素的渲染布局。
单个列表项的布局
<StackPanel Orientation="Horizontal">:让TextBlock和TextBox横向排列在一行里。<TextBlock x:Name="SearchCol" Text="{Binding Col}" Style="{StaticResource tabTextBlock}"/>:绑定当前列表项数据的Col属性,用来显示列名,同时应用了tabTextBlock这个预定义样式,统一文本的字体、颜色等外观。<TextBox x:Name="SearchText" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200">:双向绑定当前列表项数据的Filter属性,Mode=TwoWay意味着用户在TextBox里输入的内容会同步回数据源的Filter属性;UpdateSourceTrigger=PropertyChanged表示每输入一个字符就立刻更新数据源,而不是等TextBox失去焦点才更新。
TextChanged事件的命令绑定
<i:Interaction.Triggers>:这是WPF里的Blend交互行为,用来给控件添加事件触发的命令逻辑,不用在后台代码里写事件处理。<i:EventTrigger EventName="TextChanged">:监听TextBox的TextChanged事件,也就是用户输入文本时触发。<i:InvokeCommandAction Command="{Binding DataContext.SearchTextChangedCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>:触发事件时执行SearchTextChangedCommand命令。这里用RelativeSource是因为当前列表项的DataContext是Vals里的单个元素,没有这个命令,所以要向上找到ItemsControl的DataContext(也就是ViewModel)来绑定命令。
内容的提问来源于stack exchange,提问作者Tristan
相关产品推荐
相关产品推荐

