【问题标题】:Unable to get WPF .NET 5.0 ListView items to show up in the control无法让 WPF .NET 5.0 ListView 项目显示在控件中
【发布时间】:2021-06-30 00:26:31
【问题描述】:

我的应用程序中有几个 ListView 项目,我以编程方式将项目添加到其中。不幸的是,什么都没有出现。我现在尝试将ItemSource 绑定到List<SystemInfoItem> 列表无济于事。

我在互联网上进行了详尽的搜索以弄清楚如何使其工作,但无济于事。我还没想出神奇的查询。

另外,我正在尝试更改标题和行的标题背景颜色和前景色。

这是我的 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 类的代码:

public class SystemInfoItem
{
    public string Item { get; set; }
    public string Value { get; set; }
}

而且,这是我将项目添加到绑定列表的代码:

VnaSysInfoItems.Add(new SystemInfoItem() { Item = "Manufacturer", Value = VnaContainer.VnaSS.Vna_IDManuf });

【问题讨论】:

    标签: c# wpf xaml data-binding .net-5


    【解决方案1】:

    [...] 我以编程方式添加项目。
    [...] 我现在尝试将 ItemSource 绑定到 List&lt;SystemInfoItem&gt; 列表无济于事。

    是的,这是预期的行为。 ListList&lt;T&gt; 和其他集合类型不实现任何机制来通知用户界面的更改。换句话说,用户界面无法知道您何时通过添加、插入或删除项目来修改集合。会怎么样?

    对于集合类型,有一个INotifyCollectionChanged 接口,它使用CollectionChanged 事件来表示对集合的更改。好消息是,您不必自己实现它,已经有一个内置类型支持使用此接口通知集合更改。它被称为ObservableCollection&lt;T&gt;。用这种类型替换你的List&lt;T&gt;,它应该可以工作。

    public ObservableCollection<SystemInfoItem> VnaSysInfoItems { get; }
    

    属性也是如此。到目前为止,用户界面也不会检测到对项目属性 ItemValue 的更改。在那里,您可以使用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));
       }
    }
    

    【讨论】:

      【解决方案2】:

      VnaSysInfoItems的类型改为ObservableCollection&lt;SystemInfoItem&gt;。与 List&lt;T&gt; 不同,添加到 ObservableCollection&lt;T&gt; 的对象将通知 UI。

      另外,我正在尝试更改标题和行的标题背景颜色和前景色。

      设置GridViewColumnHeaderContainerStyle来改变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 属性(就像您已经完成的那样)。

      【讨论】:

      • 感谢您的提示!我已经让它工作了,但不是使用 ObservableCollection。我要把我做的事发到群里。我所做的其中一件事是在 GridView 周围包含一个 ListView.View 并向 GridViewColumns 添加一个 DataTemplate 以设置与类属性的绑定。
      【解决方案3】:

      感谢 @mm8 和 @thatguy 提供正确的替代方案!

      显然,不使用 MVVM 是不好的,但是,我正在将现有的复杂测试和测量应用程序从 WinForms 移植到 WPF .NET 5.0,所以我需要使用旧版本中可用的机制来实现第一个移植,所以我更有可能推出新版本。在 WPF 版本的第一个版本发布并实现 MVVM 之后,我将返回。它在某些地方可用,但不适用于整个应用程序。

      我最终找到了如下解决方案:

      1. 我将 ListView.View 添加到 ListView 并将 DataTemplate 添加到每个 GridViewColumns:

                    <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>
        
      2. 我使用了一个在运行时构建的列表,因为 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;
        

      【讨论】:

        猜你喜欢
        • 2018-05-02
        • 2010-12-01
        • 2010-11-12
        • 1970-01-01
        • 2017-08-28
        • 2018-10-11
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多