WPF中如何在XAML实现嵌套ObservableCollection的绑定?
XAML嵌套ObservableCollection绑定问题解决方案
问题场景
本人从事自动化领域工作,刚接触XAML,需要实现以下功能:左侧ListView展示PLC列表,点击任意PLC项后,右侧ListView显示该PLC对应的Tag集合。目前卡在XAML绑定嵌套ObservableCollection的环节,原代码中标记了困惑区域(标注为!Can't Figure this out!),优先希望通过XAML实现绑定,若无法实现再考虑后台代码方案。
相关类定义
PLC类
public class PLC { public string Name { get; set; } public ObservableCollection<Tag> Tags { get; set; } public PLC(string name) { Name = name; Tags = new ObservableCollection<Tag>(); } public override string ToString() { return Name; } }
Tag类
点击PLC项时,右侧ListView需显示该PLC关联的Tag:
public class Tag { public Tag(string name, int value) { Name = name; Value = value; } public string Name { get; set; } public int Value { get; set; } }
原XAML代码(存在绑定困惑)
此为绑定到父ViewModel的用户控件:
<UserControl x:Class="Test.UserControls.RuntimeControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="20"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Grid Grid.Row="0"> <TextBlock Foreground="Red" Margin="10,0,0,0" >Runtime</TextBlock> </Grid> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <ListView x:Name="PLCLV" Grid.Column="0" Margin="10" FontSize="25" SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Visible" BorderThickness="0" ItemsSource="{Binding PLCs}"> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}"></TextBlock> </DataTemplate> </ListView.ItemTemplate> </ListView> <ListView Grid.Column="1" Margin="10" FontSize="25" AlternationCount="2" ScrollViewer.VerticalScrollBarVisibility="Visible" BorderThickness="0 " ItemsSource=***!Can't Figure this out!***> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Focusable" Value="false"/> </Style> </ListView.ItemContainerStyle> <ListView.ItemTemplate> <DataTemplate> <TextBlock> <Run Text = "Name: "/> <Run Text =***!Can't Figure this out!*** <Run Text ="Value: "/> <Run Text =***!Can't Figure this out!*** </TextBlock> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid> </Grid> </UserControl>
修复后的XAML方案
核心绑定修改
右侧ListView的绑定可直接通过XAML实现,无需后台代码:
<ListView Grid.Column="1" Margin="10" FontSize="25" DataContext="{Binding SelectedItem, ElementName=PLCLV}" ItemsSource="{Binding Tags}"> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Focusable" Value="false"/> </Style> </ListView.ItemContainerStyle> <ListView.ItemTemplate> <DataTemplate> <TextBlock> <Run Text="Name: "/> <Run Text="{Binding Name}"/> <Run Text=" Value: "/> <Run Text="{Binding Value}"/> </TextBlock> </DataTemplate> </ListView.ItemTemplate> </ListView>
逻辑说明
- 右侧ListView通过
DataContext="{Binding SelectedItem, ElementName=PLCLV}"绑定左侧PLC列表的选中项,将自身数据上下文切换为当前选中的PLC对象。 - 通过
ItemsSource="{Binding Tags}"绑定该PLC对象的Tags集合,自动展示对应Tag列表。 - 在ItemTemplate中,通过
{Binding Name}和{Binding Value}分别绑定Tag的名称和数值。
内容的提问来源于stack exchange,提问作者captcpsc
相关产品推荐
相关产品推荐

