WPF Bind List to Multi-Column ListBox

2019-04-02 09:29发布

问题:

Since starting in WPF I am still struggling to understand the data binding functionality.

I am trying to use a multi column list box and my XAMl looks like this:

<ListBox Name="RecordList">
    <ListView Name="RecordListView">
        <ListView.View>
             <GridView>
                <GridView.Columns>
                     <GridViewColumn Header="1" Width="Auto" DisplayMemberBinding="{Binding Path=Field1}" />
                     <GridViewColumn Header="2" Width="50" DisplayMemberBinding="{Binding Path=Field2}" />
                     <GridViewColumn Header="3" Width="100" DisplayMemberBinding="{Binding Path=Field3}" />
                </GridView.Columns>
           </GridView>
      </ListView.View>
 </ListView>
</ListBox>

I just can't get the c# code right to populate the items from my list?

回答1:

Here's the way it fits together in a nutshell.

First, you define a model which holds your data for binding.

public sealed class MyListBoxItem
{
  public string Field1 {get;set;}
  public string Field2 {get;set;}
  public string Field3 {get;set;}
}

Now, you have to have a class that holds these models for binding. This type is often called the ViewModel; it presents information to the View for binding based on user input from the View. Its public properties are typically ObservableCollections and DependencyProperties so that changes in the ViewModel will be automatically picked up by the View (the UI):

public sealed class MyViewModel
{
  public ObservableCollection<MylistBoxItem> Items {get;private set;}
  public MyViewModel()
  {
    Items = new ObservableCollection<MyListBoxItem>();
    Items.Add(new MyListBoxItem{Field1="One", Field2="Two",Filed3="Three"};
  }
}

Within the codebehind for your UI, the "View", you instantiate your ViewModel and set it as the DataContext for your View.

public MyView()
{
  this.DataContext = new MyViewModel();
}

this is important as the DataContext "flows" through the visual tree. It is available to every child element on which it is set.

To display the items, I must bind the ItemsSource of the ListView to the Items property of the DataContext (this is understood). Each row within the ListView has its DataContext set to each individual MyViewModel in the Items property. So you must bind each display member to the properties of the MyListBoxItem.

<ListView Name="RecordListView" ItemsSource="{Binding Items}">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="1" Width="Auto" DisplayMemberBinding="{Binding Path=Field1}" />
                <GridViewColumn Header="2" Width="50" DisplayMemberBinding="{Binding Path=Field2}" />
                <GridViewColumn Header="3" Width="100" DisplayMemberBinding="{Binding Path=Field3}" />
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

To understand this whole process better, search for high-rated questions here tagged [MVVM].

ALSO, to help debug your bindings, configure debugging for verbose databinding:



回答2:

You dont have to use both listbox and listview.Either you use a listbox with datatemplates or use a listview with your gridviewcolumns.

Check the below links to find out how to populate a listbox properly

http://www.c-sharpcorner.com/uploadfile/mahesh/wpflistbox08252008100659am/wpflistbox.aspx

http://www.wpftutorial.net/ListBoxDataTemplate.html

http://www.codeproject.com/KB/WPF/CustomListBoxLayoutInWPF.aspx

I strongly recommend you to go through the below links and grasp a strong foundation on databinding and datatemplateing in wpf

http://msdn.microsoft.com/en-us/library/ms742521.aspx

http://www.codeproject.com/KB/WPF/GuidedTourWPF_4.aspx

http://www.wpftutorial.net/DataTemplates.html