Keywords: WPF | ListView | Data Binding
Abstract: This article delves into two primary methods for adding items to multiple columns in a WPF ListView: one focusing on C# code implementation and the other utilizing XAML for declarative definitions. By comparing traditional Windows Forms approaches with WPF's MVVM pattern, it analyzes GridViewColumn configuration, data binding mechanisms, and the definition of the MyItem class, offering practical guidance for developers migrating from WinForms to WPF.
In Windows Forms applications, adding items to multiple columns in a ListView is typically achieved by directly manipulating ListViewItem and SubItems, as shown in the following code:
public void AddItems(ListView listView)
{
var item = new ListViewItem {Text = "Some Text for Column 1"};
item.SubItems.Add("Some Text for Column 2");
listView.Items.Add(item);
}
However, in WPF, due to its adoption of the more modern MVVM (Model-View-ViewModel) architecture and robust data binding mechanisms, the implementation differs. WPF's ListView defaults to using GridView as its view, requiring developers to manage content by defining columns and data objects.
Solution with Less XAML and More C#
If you prefer to define only the basic structure of the ListView in XAML and dynamically add columns and items in C#, follow these steps. First, declare the ListView in XAML:
<ListView x:Name="listView"/>
Then, in C# code, such as in the window's constructor, configure the GridView and add items:
public Window()
{
this.InitializeComponent();
var gridView = new GridView();
this.listView.View = gridView;
gridView.Columns.Add(new GridViewColumn {
Header = "Id", DisplayMemberBinding = new Binding("Id") });
gridView.Columns.Add(new GridViewColumn {
Header = "Name", DisplayMemberBinding = new Binding("Name") });
this.listView.Items.Add(new MyItem { Id = 1, Name = "David" });
}
This method allows for flexible adjustment of column definitions at runtime but may increase code complexity.
Solution with More XAML and Less C#
Another more common approach is to define the ListView's column structure directly in XAML, leveraging WPF's declarative programming advantages. Define the ListView fully in XAML:
<ListView x:Name="listView">
<ListView.View>
<GridView>
<GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
</GridView>
</ListView.View>
</ListView>
In C#, simply add data items:
public Window()
{
this.InitializeComponent();
this.listView.Items.Add(new MyItem { Id = 1, Name = "David" });
}
This method simplifies C# code, making UI logic clearer and easier to maintain.
Definition of MyItem Class and Data Binding
In both methods, the MyItem class is used as a data model. It is defined as follows:
public class MyItem
{
public int Id { get; set; }
public string Name { get; set; }
}
By binding GridViewColumn to properties of MyItem (such as Id and Name) via the DisplayMemberBinding property, WPF automatically handles data display. This data binding mechanism is a core feature of WPF, promoting separation of concerns and decoupling UI from business logic.
When migrating from Windows Forms to WPF, developers need to adapt to this binding-based paradigm. Although it may seem complex initially, it enhances code testability and maintainability in the long run. It is recommended to choose the method based on project requirements: if the UI structure is fixed, prioritize XAML definitions; if dynamic adjustments are needed, combine with C# implementation.