无法让 WPF .NET 5.0 ListView 项目显示在控件中
Unable to get WPF .NET 5.0 ListView items to show up in the control
我的应用程序中有几个 ListView
项,我以编程方式向其中添加了项。不幸的是,什么都没有出现。我现在尝试将 ItemSource
绑定到 List<SystemInfoItem>
列表但无济于事。
我进行了详尽的 Internet 搜索以弄清楚如何使其工作,但无济于事。我还没想出神奇的查询。
此外,我正在尝试更改 header 和行的 header 背景颜色和前景色。
这是我的 xaml:
<ListView Grid.Row="1" x:Name="VnaInfoBox" Height="160" Margin="0,10,0,10" Width="400" Foreground="White" Background="Transparent"
ItemsSource="{Binding VnaSysInfoItems}">
<GridView>
<GridViewColumn x:Name="vnaInfoItemCol" Header="Item" Width="150" DisplayMemberBinding="{Binding Item}"/>
<GridViewColumn x:Name="vnaInfoValueCol" Header="Value" Width="250" DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView>
这里是 SystemInfoItem
class:
的代码
public class SystemInfoItem
{
public string Item { get; set; }
public string Value { get; set; }
}
而且,这是我将项目添加到绑定列表的代码:
VnaSysInfoItems.Add(new SystemInfoItem() { Item = "Manufacturer", Value = VnaContainer.VnaSS.Vna_IDManuf });
[...] I add items to programmatically.
[...] I've now tried binding the ItemSource
to a List<SystemInfoItem>
list to no avail.
是的,这是预期的行为。 List
、List<T>
和其他集合类型没有实现任何通知用户界面更改的机制。换句话说,用户界面无法知道您何时通过添加、插入或删除项来修改集合。会怎样?
对于集合类型,有 INotifyCollectionChanged
interface that signals changes to the collection using the CollectionChanged
event. The good news is, that you do not have to implement it yourself, there is already a built-in type that supports notifying collection changes using this interface. It is called ObservableCollection<T>
。用这种类型替换你的 List<T>
,它应该可以工作。
public ObservableCollection<SystemInfoItem> VnaSysInfoItems { get; }
属性也是如此。截至目前,用户界面也不会检测到对项目属性 Item
和 Value
的更改。在那里,您可以 implement the INotifyPropertyChanged
界面使用 PropertyChanged
事件向 属性 发出信号变化。
public class SystemInfoItem : INotifyPropertyChanged
{
private string _item;
private string _value;
public string Item
{
get => _item;
set
{
if (_item == value)
return;
_item = value;
OnPropertyChanged();
}
}
public string Value
{
get => _value;
set
{
if (_value == value)
return;
_value = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
将 VnaSysInfoItems
的类型更改为 ObservableCollection<SystemInfoItem>
。与 List<T>
不同,添加到 ObservableCollection<T>
的 objects 会通知 UI.
Also, I'm trying to change the header background color and the foreground color for both the headers and rows.
设置GridView
的ColumnHeaderContainerStyle
来改变headers的背景和前景:
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Foreground" Value="Green" />
<Setter Property="Background" Value="Yellow" />
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn x:Name="vnaInfoItemCol" Header="Item" Width="150" DisplayMemberBinding="{Binding Item}"/>
<GridViewColumn x:Name="vnaInfoValueCol" Header="Value" Width="250" DisplayMemberBinding="{Binding Value}"/>
</GridView>
要更改行的前景,您可以设置 ListView
控件本身的 Foreground
属性(就像您已经完成的那样)。
感谢@mm8 和@thatguy 提供正确的选择!
显然,不使用 MVVM 是不好的,但是,我正在将一个现有的复杂测试和测量应用程序从 WinForms 移植到 WPF .NET 5.0,因此我需要使用旧的机制实现第一个移植版本,这样我就更有可能推出新版本。我将在首次发布 WPF 版本并实施 MVVM 后返回。它在某些地方可用,但不是在整个应用程序中可用。
我最终找到了如下解决方案:
我在每个 GridViewColumns 的 ListView 和 DataTemplate 中添加了一个 ListView.View:
<ListView Grid.Row="1" x:Name="VnaInfoBox" Height="160" Margin="0,10,0,10" Width="400" Foreground="White" Background="Transparent">
<ListView.View>
<GridView>
<GridViewColumn Header="Item" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Item}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Value" Width="240" DisplayMemberBinding="{Binding Value}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Value}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
我使用了一个在运行时构建的列表,因为 ListView 中的项目发生变化并分配给 ListView.ItemsSource:
// Create the VnaInfoBox data source
List<SystemInfoItem> vnaInfo = new List<SystemInfoItem>();
vnaInfo.Add(new SystemInfoItem() { Item = "Manufacturer", Value = "Ford" });
vnaInfo.Add(new SystemInfoItem() { Item = "Model", Value = "Model A" });
vnaInfo.Add(new SystemInfoItem() { Item = "Serial #", Value = "23456" });
vnaInfo.Add(new SystemInfoItem() { Item = "Version", Value = "3.4" });
vnaInfo.Add(new SystemInfoItem() { Item = "Options", Value = "Convertable" });
VnaInfoBox.ItemsSource = vnaInfo;
我的应用程序中有几个 ListView
项,我以编程方式向其中添加了项。不幸的是,什么都没有出现。我现在尝试将 ItemSource
绑定到 List<SystemInfoItem>
列表但无济于事。
我进行了详尽的 Internet 搜索以弄清楚如何使其工作,但无济于事。我还没想出神奇的查询。
此外,我正在尝试更改 header 和行的 header 背景颜色和前景色。
这是我的 xaml:
<ListView Grid.Row="1" x:Name="VnaInfoBox" Height="160" Margin="0,10,0,10" Width="400" Foreground="White" Background="Transparent"
ItemsSource="{Binding VnaSysInfoItems}">
<GridView>
<GridViewColumn x:Name="vnaInfoItemCol" Header="Item" Width="150" DisplayMemberBinding="{Binding Item}"/>
<GridViewColumn x:Name="vnaInfoValueCol" Header="Value" Width="250" DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView>
这里是 SystemInfoItem
class:
public class SystemInfoItem
{
public string Item { get; set; }
public string Value { get; set; }
}
而且,这是我将项目添加到绑定列表的代码:
VnaSysInfoItems.Add(new SystemInfoItem() { Item = "Manufacturer", Value = VnaContainer.VnaSS.Vna_IDManuf });
[...] I add items to programmatically.
[...] I've now tried binding theItemSource
to aList<SystemInfoItem>
list to no avail.
是的,这是预期的行为。 List
、List<T>
和其他集合类型没有实现任何通知用户界面更改的机制。换句话说,用户界面无法知道您何时通过添加、插入或删除项来修改集合。会怎样?
对于集合类型,有 INotifyCollectionChanged
interface that signals changes to the collection using the CollectionChanged
event. The good news is, that you do not have to implement it yourself, there is already a built-in type that supports notifying collection changes using this interface. It is called ObservableCollection<T>
。用这种类型替换你的 List<T>
,它应该可以工作。
public ObservableCollection<SystemInfoItem> VnaSysInfoItems { get; }
属性也是如此。截至目前,用户界面也不会检测到对项目属性 Item
和 Value
的更改。在那里,您可以 implement the INotifyPropertyChanged
界面使用 PropertyChanged
事件向 属性 发出信号变化。
public class SystemInfoItem : INotifyPropertyChanged
{
private string _item;
private string _value;
public string Item
{
get => _item;
set
{
if (_item == value)
return;
_item = value;
OnPropertyChanged();
}
}
public string Value
{
get => _value;
set
{
if (_value == value)
return;
_value = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
将 VnaSysInfoItems
的类型更改为 ObservableCollection<SystemInfoItem>
。与 List<T>
不同,添加到 ObservableCollection<T>
的 objects 会通知 UI.
Also, I'm trying to change the header background color and the foreground color for both the headers and rows.
设置GridView
的ColumnHeaderContainerStyle
来改变headers的背景和前景:
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Foreground" Value="Green" />
<Setter Property="Background" Value="Yellow" />
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn x:Name="vnaInfoItemCol" Header="Item" Width="150" DisplayMemberBinding="{Binding Item}"/>
<GridViewColumn x:Name="vnaInfoValueCol" Header="Value" Width="250" DisplayMemberBinding="{Binding Value}"/>
</GridView>
要更改行的前景,您可以设置 ListView
控件本身的 Foreground
属性(就像您已经完成的那样)。
感谢@mm8 和@thatguy 提供正确的选择!
显然,不使用 MVVM 是不好的,但是,我正在将一个现有的复杂测试和测量应用程序从 WinForms 移植到 WPF .NET 5.0,因此我需要使用旧的机制实现第一个移植版本,这样我就更有可能推出新版本。我将在首次发布 WPF 版本并实施 MVVM 后返回。它在某些地方可用,但不是在整个应用程序中可用。
我最终找到了如下解决方案:
我在每个 GridViewColumns 的 ListView 和 DataTemplate 中添加了一个 ListView.View:
<ListView Grid.Row="1" x:Name="VnaInfoBox" Height="160" Margin="0,10,0,10" Width="400" Foreground="White" Background="Transparent"> <ListView.View> <GridView> <GridViewColumn Header="Item" Width="150"> <GridViewColumn.CellTemplate> <DataTemplate> <ContentControl Content="{Binding Item}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Value" Width="240" DisplayMemberBinding="{Binding Value}"> <GridViewColumn.CellTemplate> <DataTemplate> <ContentControl Content="{Binding Value}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
我使用了一个在运行时构建的列表,因为 ListView 中的项目发生变化并分配给 ListView.ItemsSource:
// Create the VnaInfoBox data source List<SystemInfoItem> vnaInfo = new List<SystemInfoItem>(); vnaInfo.Add(new SystemInfoItem() { Item = "Manufacturer", Value = "Ford" }); vnaInfo.Add(new SystemInfoItem() { Item = "Model", Value = "Model A" }); vnaInfo.Add(new SystemInfoItem() { Item = "Serial #", Value = "23456" }); vnaInfo.Add(new SystemInfoItem() { Item = "Version", Value = "3.4" }); vnaInfo.Add(new SystemInfoItem() { Item = "Options", Value = "Convertable" }); VnaInfoBox.ItemsSource = vnaInfo;