1

I'm new to data binding in WPF and trying to understand concepts. What I'm trying to do is bind observable collection data to list view. For that purposes I have created two classes:

public class Employee_list
    {
        public ObservableCollection<Employee> list = new ObservableCollection <Employee>();
        public Employee_list()
        {
        }
    }

    public class Employee
    {
        public string name { get; set; }
        public string surname { get; set;}
        public Employee(string name, string surname)
        {
            this.name = name;
            this.surname = surname;
        }
    }

In the main window I've instantiated my list of Employees:

    public MainWindow()
    {
        InitializeComponent();
        Employee_list l = new Employee_list() { list = { new Employee("Alex", "Z"), new Employee ("Alex", "K")}};            
    }

Now I need to bind content of this list to ListView:

I understand that I can do it in three ways as per - 1

  1. RelativeSource: Relative source is one of the properties on a binding that can point to relative source markup extension that tells where the source can be found in hierarchy. In simple words, it is the relative path in the element hierarchy.

  2. ElementName: Another way of specifying a source is by using an ElementName in which another element is present in the current UI that can be used as a source object. Here the source object must be part of the visual tree.

  3. Source: Another way is by using the Source property on a binding. This source property must point to some object reference and the only better way to get an object reference down into the Source property is to use a static resource that points to some object in a resource collection.

I'm try to do it via Source and Resources, but in that case I am able to specify class itself and not a specific collection with content:

<Window.Resources>
    <localc:Employee_list x:Key="EmployeeList" />
</Window.Resources>

Could you please help me to understand how I can do it and what is the proper way to do it?

XAML:

<Window x:Name="mw" 
x:Class="binding_testing.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:localc="clr-namespace:binding_testing"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <localc:Employee_list x:Key="EmployeeList" />
</Window.Resources>
<Grid>
    <ListView Name="myListBox" HorizontalAlignment="Left" Height="89" Margin="75,77,0,0" VerticalAlignment="Top" Width="393"
         ItemsSource="{Binding Source={StaticResource EmployeeList}}" >
        <ListView.View>
            <GridView >
                <GridViewColumn Header="Surname" Width="Auto" DisplayMemberBinding="{Binding surname}" />
                <GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding name}" />
            </GridView>
        </ListView.View>
    </ListView>

</Grid>
</Window>
Dmytro
  • 196
  • 1
  • 8
  • 19

2 Answers2

4

So first name your Classes clear! Here you find the Microsoft Naming Guidelines.

I renamed your classes and properties to this:

public class EmployeeList
{
    public ObservableCollection<Employee> List { get; set; } = new ObservableCollection<Employee>();
}

public class Employee
{
    public string Name { get; set; }
    public string SurName { get; set; }
    public Employee(string name, string surName)
    {
        this.Name = name;
        this.SurName = surName;
    }
}

Make sure that all Properties are public and also are properties. Because List was just a field in your code.

Then i recommend to introduce the class View. This is also a concept of the MVVM pattern, but i think it makes the code easier so this is good in two ways:

public class View
{
    public EmployeeList EmployeeList { get; set; }

    public View()
    {
        EmployeeList = new EmployeeList() { List = { new Employee("Alex", "Z"), new Employee("Alex", "K") } };
    }
}

As you can see View holds an instance of the EmployeeList.


Now you just need to set the DataContext of your window to the View and bind to the properties you want to:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new View();
    }
}

The above code creates a new instance of the View class and sets this as the new DataContext.

Now you just need to bind the ItemsSource of the ListView to EmployeeList.List and set the DisplayMemeberBindings:

<Grid>
    <ListView ItemsSource="{Binding EmployeeList.List}" >
        <ListView.View>
            <GridView >
                <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding SurName}" />
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

The Problems of your code were that you had two instances of EmployeeList

  1. Defined in the XAML
  2. Created in the Constructor of the Window

Moreover you were not able to bind to the ObservableCollection because it was not a Property. You only can bind to properties. A binding to fields is not possible. So make clear you have a get {...} or/and set {...} for the properties you want.

Jens
  • 2,592
  • 2
  • 21
  • 41
0

Do following changes :

  1. Expose your collection as a property as DataBinding works with properties and not fields.

    public class Employee_list
    { 
        ObservableCollection<Employee> list = new ObservableCollection <Employee>();
    
        public ObservableCollection<Employee> List1
        {
            get { return list; }
        }
    
        public Employee_list()
        {
            List1.Add(new Employee("Alex", "Z"));
            List1.Add(new Employee("Alex", "K"));
        }
    }
    
  2. Instead of ItemsSource, bind DataContext, and then use your Collection property as ItemsSource like :

    <ListView ... 
         DataContext="{Binding Source={StaticResource EmployeeList}}" ItemsSource="{Binding List1}" >
    

Few good links :

  1. DataBinding - How to
  2. DataBinding - FAQ
  3. Scott's DataBinding tutorial
AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38