C# WPF:将ListView绑定到数据结构
我想将下面这样的数据结构绑定到ListView或类似组件。预期结果如下图所示C# WPF:将ListView绑定到数据结构,c#,wpf,xaml,listview,C#,Wpf,Xaml,Listview,我想将下面这样的数据结构绑定到ListView或类似组件。预期结果如下图所示 public struct Info { public string Port; public byte FwVersion; public byte ApiVersion; public byte BootVersion; public char[] BoardId; public char[] AfeId; public AfeType AfeType; }
public struct Info
{
public string Port;
public byte FwVersion;
public byte ApiVersion;
public byte BootVersion;
public char[] BoardId;
public char[] AfeId;
public AfeType AfeType;
}
我知道可以将结构内容放入一个对象数组,然后将该数组绑定到ListView,但我更愿意在xaml中定义ListView行名称,并直接绑定到底层结构,例如:
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" />
<GridViewColumn Header="Value" Width="240" />
</GridView>
<ListView.View>
<ListViewItem>
<ListViewColumn Column="1">Serial port</ListViewColumn>
<ListViewColumn Column="2">{Binding MyStructure.Port}</ListViewColumn>
</ListViewItem>
<ListViewItem>
<ListViewColumn Column="1">Board ID</ListViewColumn>
<ListViewColumn Column="2">{Binding MyStructure.BoardId}</ListViewColumn>
</ListViewItem>
...
</ListView>
串口
{绑定MyStructure.Port}
板ID
{绑定MyStructure.BoardId}
...
不幸的是,我不知道如何在xaml中定义“硬编码”行
感谢您的想法。手动添加具有不同绑定对象的ListViewItems的方式使得几乎不可能绑定到多个对象。但有两种方法可以做到这一点: 1) 使您拥有ListViewItem(扩展并修改它),或 2) 在listview中,将不同的属性声明为列,例如:
<ListView x:Name = "LWBoards">
<ListView.View>
<GridView>
<GridViewColumn Header="Serial port" Width="auto" DisplayMemberBinding="{Binding Port}"/>
<GridViewColumn Header="Board ID" Width="auto" DisplayMemberBinding="{Binding BoardId}"/>
<...>
<GridViewColumn Header="AFE ID" Width="auto" DisplayMemberBinding="{Binding AfeId}"/>
<GridViewColumn Header="AFE Type" Width="auto" DisplayMemberBinding="{Binding AfeType}"/>
</GridView>
<ListView.View>
</ListView>
使用不同的绑定对象逐个手动添加ListViewItems的方式,几乎不可能绑定到多个对象。但有两种方法可以做到这一点: 1) 使您拥有ListViewItem(扩展并修改它),或 2) 在listview中,将不同的属性声明为列,例如:
<ListView x:Name = "LWBoards">
<ListView.View>
<GridView>
<GridViewColumn Header="Serial port" Width="auto" DisplayMemberBinding="{Binding Port}"/>
<GridViewColumn Header="Board ID" Width="auto" DisplayMemberBinding="{Binding BoardId}"/>
<...>
<GridViewColumn Header="AFE ID" Width="auto" DisplayMemberBinding="{Binding AfeId}"/>
<GridViewColumn Header="AFE Type" Width="auto" DisplayMemberBinding="{Binding AfeType}"/>
</GridView>
<ListView.View>
</ListView>
最简单的解决方案是将
ICollection
添加到您的DataContext
中。假设您使用的是MVVM,ListViewBindingExampleViewModel
是视图的DataContext
(可能是窗口
,页面
或用户控件
)。所以,你应该:
公共类ListViewBindingExampleViewModel
{
公共列表信息{get;set;}=new List();
私有ListViewBindingExampleViewModel(){}
}
然后,在xaml中:
串口
{绑定路径=端口}
板ID
{绑定路径=BoardId}
还值得一提的是,Infos
列表项的更改不会以这种方式传播到前端
在我看来,解决这个问题的最佳方法是使用,ViewModel
有一个BindableCollection
,它将绑定到列表视图的ItemsSource
。例如,在视图模型中,您有
公共类ListViewBindingExampleViewModel
{
public BindableCollection Infos{get;set;}=new BindableCollection();
私有ListViewBindingExampleViewModel(){}
}
然后,您应该更改Info
类以实现INotifyPropertyChanged
接口,如下所示:
公共结构信息:PropertyChangedBase
{
专用字符串\u端口;
...
公共字符串端口{get{return}Port;}set{u Port=value;NotifyOfPropertyChange(nameof(Port));}
...
}
这样做,如果您需要,后端的更改将反映在前端。最简单的解决方案是在您的数据上下文中添加ICollection
。假设您使用的是MVVM,ListViewBindingExampleViewModel
是视图的DataContext
(可能是窗口
,页面
或用户控件
)。所以,你应该:
公共类ListViewBindingExampleViewModel
{
公共列表信息{get;set;}=new List();
私有ListViewBindingExampleViewModel(){}
}
然后,在xaml中:
串口
{绑定路径=端口}
板ID
{绑定路径=BoardId}
还值得一提的是,Infos
列表项的更改不会以这种方式传播到前端
在我看来,解决这个问题的最佳方法是使用,ViewModel
有一个BindableCollection
,它将绑定到列表视图的ItemsSource
。例如,在视图模型中,您有
公共类ListViewBindingExampleViewModel
{
public BindableCollection Infos{get;set;}=new BindableCollection();
私有ListViewBindingExampleViewModel(){}
}
然后,您应该更改Info
类以实现INotifyPropertyChanged
接口,如下所示:
公共结构信息:PropertyChangedBase
{
专用字符串\u端口;
...
公共字符串端口{get{return}Port;}set{u Port=value;NotifyOfPropertyChange(nameof(Port));}
...
}
这样做,如果需要,后端中的更改将反映在前端。最后,最简单的方法是创建一个单独的视图模型类,该类将模型数据转换为一个可以轻松绑定到ListView的集合。该解决方案与Rafael Camelo的解决方案非常相似,但与评论不符
使用这种方法时,字段名和描述不是用Xaml编写的,而是在视图模型类中编写的,但最后,对于我的用例来说,这是更好的解决方案。我最终是如何做到的:
- 实现了
DataRow
类实现INotifyPropertyChanged
接口。该类提供变量名、值和ListView组。当值更改时,PropertyChangedEventHandler
将更改传播到用户界面
- 已实现类
ListViewModel
已实现IReadOnlyList,INotifyCollectionChanged
。此类从模型中提取所需的结构并将其转换为集合。