Revils
Revils

Reputation: 1508

Data binding CollectionViewSource and GridView

I have a problem displaying data in a GridView. I cannot seem to get it right and I could not find any other topics regarding this. Probably I'm overseeing something really simple.

I have got this gridview:

<GridView ItemsSource="{Binding Source={StaticResource itemsViewSource}}" Width="383" Height="216"/>
<Button Content="Button" Click="Button_Click" />

I have got this CollectionViewSource:

<Page.Resources>
    <CollectionViewSource x:Name="itemsViewSource" Source="{Binding NamesList, Mode=TwoWay}"/>
</Page.Resources>

And this Code behind:

Person Class:

    public class Person : INotifyPropertyChanged {
    private string m_name;
    private string m_gender;
    public event PropertyChangedEventHandler PropertyChanged;

    public string Name {
        get {
            return m_name;
        }
        set {
            m_name = value;
            RaisePropertyChanged("Name");
        }
    }
    public string Gender {
        get {
            return m_gender;
        }
        set {
            m_gender = value;
            RaisePropertyChanged("Gender");
        }
    }
    protected void RaisePropertyChanged(string PropertyName) {
        var eventhandler = this.PropertyChanged;
        if (eventhandler != null) {
            eventhandler(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
}

Mainpage:

public sealed partial class MainPage : Page{
    public ObservableCollection<Person> NamesList {get; set;}

    public MainPage(){
        this.InitializeComponent();

        Person p = new Person();
        Person p2 = new Person();
        Person p3 = new Person();

        p.Name = "Piet";
        p.Gender = "Male";
        p2.Name = "Pietin";
        p2.Gender = "Female";
        p3.Name = "Piet de tweede";
        p3.Gender = "Male";

        NamesList = new ObservableCollection<Person>();
        NamesList.Add(p);
        NamesList.Add(p2); 
        NamesList.Add(p3);
    }

:   private void Button_Click(object sender, RoutedEventArgs e) {
        itemsViewSource.Source = NamesList;
    }
}

Why is my GridView not showing any data or adding data on button clicks?

@edit 16:16 - 15-09-2014 If after the click I add the following, it shows the items. But that is not how it is supposed to be.

itemsViewSource.Source = NamesList;

@edit 09:04 - 16-09-2014 I added this debugging image to show that the binding is good, he can find the NamesList. But if I look at the itemsViewSource it says the Source is null. ItemsViewSource Debugging

Upvotes: 1

Views: 819

Answers (2)

Revils
Revils

Reputation: 1508

I have found two answers.

Answer 1:

Simply add this to the < page >

DataContext="{Binding RelativeSource={RelativeSource Self}}

Answer 2:

I have to set the DataContext in the Mainpage and refer it to a Class (In my case a Person class) (In my opinion it is not logical and setting the following line of code is way easier:

itemsViewSource.Source = NamesList; 

I have made the following adaptions;

MainPage:

public sealed partial class MainPage : Page{
    public MainPage(){
        this.InitializeComponent();
        DataContext = new Person();
    }
}

Person Class (Added the following) (I have to see this more as a Data Class):

    public ObservableCollection<Person> NamesList { get; set; }
    public Person() {
        Person p = new Person("Piet", "Male");
        Person p2 = new Person("Pietin", "Female");
        NamesList = new ObservableCollection<Person>();
        NamesList.Add(p);
        NamesList.Add(p2);
    }
    public Person(string Name, string Gender){
        m_name = Name;
        m_gender = Gender;
    }

If I set it up like this I am able to use the source binding of the CollectionViewSource correctly. (Where the source binding was null before.)

<CollectionViewSource x:Name="itemsViewSource" Source="{Binding NamesList, Mode=TwoWay}"/>

Upvotes: 0

GazTheDestroyer
GazTheDestroyer

Reputation: 21261

Since you are using a plain List<T>, WPF has no way of knowing when items are added or removed.

Try using an ObservableCollection<T> instead.

EDIT:

NamesList needs to be a property. WPF can only bind to properties:

public sealed partial class MainPage : Page
{
    public ObservableCollection<Person> NamesList  { get; private set; }

    public MainPage(){
        this.InitializeComponent();
        Person p = new Person();
        Person p2 = new Person();

        p.Name = "Piet";
        p.Gender = "Male";
        p2.Name = "Pietin";
        p2.Gender = "Female";

        NamesList = new ObservableCollection<Person>();
        NamesList.Add(p);
        NamesList.Add(p2); 
    }

Upvotes: 2

Related Questions