如何将包含多个列的项添加到WPF listview控件

编程入门 行业动态 更新时间:2024-10-22 19:33:52
本文介绍了如何将包含多个列的项添加到WPF listview控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

这是我第一次尝试使用WPF ListView控件。我已经广泛使用了WinForms ListView控件,但这并没有帮助我解决这个问题。当我向WPF ListView控件添加多列项时,我得到这两个错误。 使用Visual Studio Debugger Quick Watch,我可以看到 DirectCast((New System.Linq.SystemCore_EnumerableDebugView(lstCSchedule.Items).Items(0) )),System.Windows.Controls.ContentControl).Content 对象包含Name和RecordDateTime属性名称和值,但除了列标题和空行之外,ListView控件中不显示任何内容。这告诉我数据被放入ListView控件,但ListView控件不显示它。 我可以使用什么语法将行正确添加到ListView Items集合中,以便它显示在ListView控件中并且不会导致错误消息? 运行时错误消息 System.Windows.Data错误:40:BindingExpression路径错误:在对象''CRecordSchedule'(HashCode = 18437496)'上找不到名称属性。 BindingExpression:路径=名称; DataItem ='CRecordSchedule'(HashCode = 18437496); target元素是'TextBlock'(Name =''); target属性为'Text'(类型'String') System.Windows.Data错误:40:BindingExpression路径错误:'对象'找不到'RecordDateTime'属性'''CRecordSchedule'(HashCode = 18437496)'。 BindingExpression:路径= RecordDateTime; DataItem ='CRecordSchedule'(HashCode = 18437496); target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String') XAML WPF ListView控件的定义

This is my first attempt at using a WPF ListView control. I have used the WinForms ListView control extensively but that hasn't helped me solve this issue. I get these two errors when I add a multi-column item to the WPF ListView control. Using the Visual Studio Debugger Quick Watch, I can see that the DirectCast((New System.Linq.SystemCore_EnumerableDebugView(lstCSchedule.Items).Items(0)), System.Windows.Controls.ContentControl).Content object contains both the Name and the RecordDateTime property names and values but nothing is displayed in the ListView control other than the column headings and a blank row. That tells me that the data is getting put into the ListView control but it is not displayed by the ListView control. What syntax can I use to properly add a row to the ListView Items collection so that it displays in the ListView control and doesn't cause an error message? Run-Time Error Messages System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''CRecordSchedule' (HashCode=18437496)'. BindingExpression:Path=Name; DataItem='CRecordSchedule' (HashCode=18437496); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'RecordDateTime' property not found on 'object' ''CRecordSchedule' (HashCode=18437496)'. BindingExpression:Path=RecordDateTime; DataItem='CRecordSchedule' (HashCode=18437496); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') XAML WPF Definition of the ListView Control

<ListView x:Name="lstCSchedule" HorizontalAlignment="Left" Height="108" Margin="27,88,0,0" VerticalAlignment="Top"> <ListView.View> <GridView> <GridViewColumn Width="120" Header="Name" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Width="90" Header="Record DateTime" DisplayMemberBinding="{Binding RecordDateTime}" /> </GridView> </ListView.View> </ListView>

CRecordSchedule类定义

The CRecordSchedule Class Definition

Public Class CRecordSchedule Public Name As String Public RecordDateTime As String Public Sub New(n As String, r As String) Name = n RecordDateTime = r End Sub End Class

向ListView控件添加一个新项目的代码

The code that adds one new item to the ListView control

Dim Schedule As New CRecordSchedule("A Test Show Title", "06/14/18 7:00PM") Dim lvItem As New ListViewItem lvItem.Content = Schedule lstCSchedule.Items.Add(lvItem)

我的尝试: 1. lstCSchedule.Items.Add(Schedule) 2.添加一个数组到ListView Items集合而不是类对象。 3. DisplayMemberBinding ={Binding Path = Name}和DisplayMemberBinding ={Binding Path = RecordDateTime} 4.基本相同的尝试解决方案的许多其他迭代。

What I have tried: 1. lstCSchedule.Items.Add(Schedule) 2. Add an array to the ListView Items collection instead of a class object. 3. DisplayMemberBinding="{Binding Path=Name}" and DisplayMemberBinding="{Binding Path=RecordDateTime}" 4. Numerous other iterations of basically the same attempted solutions.

推荐答案

错误消息是所需内容的最佳指标。 WPF数据绑定 [ ^ 对于WinForm数据绑定系统来说,它更加优越和简单。一旦你花时间学习数据绑定在WPF中的工作方式,你就不会回头了。 这里有一个例子,你可以快速告诉你如何数据绑定有效: WPF绑定属性更新需要为每个属性触发 PropertyChanged 事件。对于集合,我们可以使用一个名为 ObservableCollection 的专门集合类,它会触发 CollectionChanged 事件。 对于属性,下面是一个基类,用于简化类中每个属性所需的重复代码: The error message is the best indicator of what is required. WPF Data Binding[^] is far superior and simpler to the WinForm Data Binding system. Once you invest the time to learn how data binding works in WPF, you won't want to look back. Here is an example for you to show you quickly how Data Binding works: WPF Binding for property updates requires a PropertyChanged event to be fired for each property. For collections, we can use a specialized collection class called ObservableCollection which fires a CollectionChanged event. For the properties, below is a base class to simplify the repetitive code required for each property in a class: Public MustInherit Class ObservableBase Implements INotifyPropertyChanged Public Event PropertyChanged As PropertyChangedEventHandler _ Implements INotifyPropertyChanged.PropertyChanged Public Sub [Set](Of TValue)(ByRef field As TValue, ByVal newValue As TValue, <CallerMemberName> ByVal Optional propertyName As String = "") If EqualityComparer(Of TValue).[Default].Equals(field, Nothing) OrElse Not field.Equals(newValue) Then field = newValue RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) End If End Sub End Class

对于这个例子,我将使用一个 PersonModel 类继承上面的 ObservableBase 基类:

For this example, I will use a PersonModel class which inherits the ObservableBase base class above:

Public Class PersonModel Inherits ObservableBase Private mName As String Public Property Name As String Get Return mName End Get Set(ByVal value As String) [Set](mName, value) End Set End Property Private mAge As Integer Public Property Age As Integer Get Return mAge End Get Set(ByVal value As Integer) [Set](mAge, value) End Set End Property End Class

现在我们可以创建我们的集合并添加一个 事件来演示实际中的绑定系统:

Now we can create our collection and add a event to demonstrate the binding system in action:

Imports System.Collections.ObjectModel Class MainWindow Public Sub New() InitializeComponent() DataContext = Me Mock() End Sub Public Property Persons As ObservableCollection(Of PersonModel) = New ObservableCollection(Of PersonModel)() Private rand As Random = New Random() Private Sub Mock() For i As Integer = 0 To 10 - 1 Persons.Add(New PersonModel With { .Name = String.Format("Person {0}", i), .Age = rand.[Next](20, 50) }) Next End Sub Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) For Each person In Persons person.Age = rand.[Next](20, 50) Next End Sub End Class

在上面的代码隐藏页面中,我将表单的 DataContext 设置为代码隐藏页面本身。这将允许UI(XAML)查看绑定通知并更新显示。 最后,我们可以绑定 UI元素代码隐藏的属性

In the above code-behind page, I set the form's DataContext to the code-behind page itself. This will allow the UI (XAML) to see the binding notifications and update the display. Lastly, we can bind the properties of the code-behind to the UI elements:

<Window x:Class="MainWindow" xmlns="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/winfx/2006/xaml" mc:Ignorable="d" xmlns:d="schemas.microsoft/expression/blend/2008" xmlns:mc="schemas.openxmlformats/markup-compatibility/2006" xmlns:local="clr-namespace:WpfSimpleBindingVB" Title="MainWindow" WindowStartupLocation="CenterScreen" Height="400" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.Resources> <DataTemplate DataType="{x:Type local:PersonModel}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Name}" Margin="10 3"/> <TextBlock Text="{Binding Age}" Margin="10 3" Grid.Column="1"/> </Grid> </DataTemplate> </Grid.Resources> <ListBox ItemsSource="{Binding Persons}"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> </Style> </ListBox.ItemContainerStyle> </ListBox> <Button Content="Randomize" Padding="10 5" Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Click="Button_Click"/> </Grid> </Window>

上面的示例使用ListBox控件。 ListView的原理完全相同。以下是使用ListView的UI:

The above example uses a ListBox control. The principles for the ListView is exactly the same. Here is the UI using the ListView instead:

<Window x:Class="MainWindow" xmlns="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/winfx/2006/xaml" mc:Ignorable="d" xmlns:d="schemas.microsoft/expression/blend/2008" xmlns:mc="schemas.openxmlformats/markup-compatibility/2006" xmlns:local="clr-namespace:WpfSimpleBindingVB" Title="MainWindow" WindowStartupLocation="CenterScreen" Height="400" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <ListView ItemsSource="{Binding Persons}"> <ListView.View> <GridView> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" /> </GridView> </ListView.View> </ListView> <Button Content="Randomize" Padding="10 5" Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Click="Button_Click"/> </Grid> </Window>

This example is using the same data binding technique used in the MVVM (Model View ViewModel) Design Pattern except the View Model is in the code behind. MVVM is a little bit more involved and is beyond the scope of this answer but worthwhile investing the time in learning.

This example is using the same data binding technique used in the MVVM (Model View ViewModel) Design Pattern except the ViewModel is in the code behind. MVVM is a little bit more involved and is beyond the scope of this answer but worthwhile investing the time in learning.

I have solved my problem. I changed the class definition by adding a Public Property for Name and RecordDateTime. I have solved my problem. I changed the class definition by adding a Public Property for Name and RecordDateTime. Public Class CSchedule Private mName As String Private mRecordDateTime As String Public Sub New(ByVal Name As String, ByVal RecordDateTime As String) mName = Name mRecordDateTime = RecordDateTime End Sub Public Property Name As String Get Name = mName End Get Set(value As String) mName = value End Set End Property Public Property RecordDateTime As String Get RecordDateTime = mRecordDateTime End Get Set(value As String) mRecordDateTime = value End Set End Property End Class

Dim Schedule As New CRecordSchedule(rs.GetString(rs.GetOrdinal("name")), Format(rs.GetDateTime(rs.GetOrdinal("rundatetime")), "MM/dd/yy hh:mm:sstt")) lstCSchedule.Items.Add(Schedule)

To diagnose this issue, I added trace declarations to the XAML for the ListView columns. One of the trace messages said that the Accessor was null. I guessed that meant that I had to explicitly declare a Public Property for Name and RecordDateTime. The conclusion is that the binding mechanism can’t find the values in a class object unless the properties are explicitly declared.

To diagnose this issue, I added trace declarations to the XAML for the ListView columns. One of the trace messages said that the Accessor was null. I guessed that meant that I had to explicitly declare a Public Property for Name and RecordDateTime. The conclusion is that the binding mechanism can't find the values in a class object unless the properties are explicitly declared.

<ListView x:Name="lstCSchedule" HorizontalAlignment="Left" Height="108" Margin="1,88,0,0" VerticalAlignment="Top" Grid.Column="1" > <ListView.View> <GridView> <GridViewColumn Width="90" Header="Name" PresentationTraceSources.TraceLevel="High" DisplayMemberBinding="{Binding Name,diag:PresentationTraceSources.TraceLevel=High}" /> <GridViewColumn Width="90" Header="Record DateTime" PresentationTraceSources.TraceLevel="High" DisplayMemberBinding="{Binding RecordDateTime,diag:PresentationTraceSources.TraceLevel=High}" /> </GridView> </ListView.View> </ListView>

更多推荐

如何将包含多个列的项添加到WPF listview控件

本文发布于:2023-11-23 15:53:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1622027.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   控件   如何将   WPF   listview

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!