ExtremeSwat
ExtremeSwat

Reputation: 824

WPF Data Binding confusion

I've just started taking up a course about WPF and I'm a bit confuse about some areas related to Data-Binding. I have no syntax issue, but most probably committed some newbie errors and I have couple of questions.

I've done a simple screen with 2 textboxes and I when I click a button these two items are added to a ListBox.

Reference within the Window tag of the XAML to the People class

 xmlns:classes="clr-namespace:WPF_Course.Classes"

Added a Window resource

<Window.Resources>
        <classes:People x:Key="people"/>
</Window.Resources>

Here's how I've declared my Listbox

<ListBox DataContext="{Binding Source={StaticResource people}}"
                 ItemsSource="{Binding Persons}"
                 x:Name="PersonListBox">

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <StackPanel>
                            <TextBlock Text="{Binding FullName}"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>

            </ListBox.ItemTemplate>                
</ListBox>

So, I've added a DataContext to my ListBox where I bind it to my people resource and also I add an ItemSource which looks on a property within my People .

This is my class

public class People : ObservableCollection<Person> 
    {
        public ObservableCollection<Person> Persons { get { return persons; } set { persons = value; } }
        private ObservableCollection<Person> persons = new ObservableCollection<Person>();

        public People()
        {
            for (int i = 0; i < 1; i++)
            {
                // implicitly I add one item just for messing around with the constructor
                Persons.Add(new Person()
                {
                    Name = "Dummy",
                    LastName = "Dummy",
                    Age = 15
                });
            }
        }
    }

Based on what I've done so far I have the following questions :

1) What's the difference between (they have the same effect, but there's more reasoning behind it ? )

ItemsSource = "{Binding Persons}"

and

ItemsSource = "{Binding Path = Persons }"

Also by leaving the ItemSource = "{Binding}" am I actually just instantiating the a People instance, thus all my logic being treated from the constructor of that class ? I've messed around with it and it appears to do so, but I am not sure.

2) On my Peoples class I've Implemented the ObservableCollection<Person> (where Person is also a class). Initially I was doing a static addition to my list from the constructor itself and I had no properties defined within the class ( ObservableCollection<person> type of properties ) thus needing it ( the implementatiton of the interface) but now using a property do I really need it? , so my question is :

If my class's sole purpose is to load things within it's collection from the constructor only ( and not from an outside class, thus needing some sort of a property ), is it a best practice to implement my class with the ObservableCollection<myClass> or to define properties of the same type that I've done ? (for accessing from an outside class)

I am sorry for the weird questions because I know they sound somewhat silly, I'm looking from a validation because I've just started working with wpf recently.

Thanks

Edit 2 : Thank you for all your answers, I understood now. Also I've forgotten to show you how I insert data in my collection. ( Added this edit for me to remember if I forget it and for others that may stumble upon this thread having a similar confusion )

 ObservableCollection<Person> ppl;
    public MainWindow()
        {
            InitializeComponent();
            person = new Person();
            stackPanelPerson.DataContext = person;

            people = new People();
            ppl = people.Persons;
            PersonListBox.ItemsSource = ppl;
        }

Initially I was doing like this

 ppl.Add(new Person() { Name = boxFirstName.Text, LastName = boxLastName.Text, Age = Int32.Parse(boxAge.Text) });

Then I realized I was using data-binding on my Person Class(INotifyPropertyChanged) with properties so I changed it to :

 ppl.Add(new Person() { Name = person.Name, LastName = person.LastName, Age = person.Age});

Thanks again guys for the replies !! Have a good day !

Upvotes: 4

Views: 365

Answers (4)

Kalpak Kitukale
Kalpak Kitukale

Reputation: 1

  1. None, there is no difference. {Binding propertyName} is the same as {Binding Path=propertyName}, it's almost like a shortcut, but Constructor get called because of DataContext="{Binding Source={StaticResource people}}".

  2. It depends. You don't have to use ObservableCollection<> if collection is not going to change after you bind to it. Creating List<>, filling it up and then binding to it will work pretty well.But if you want to change collection from screen and update list then you need to go for ObservableCollection<>

Upvotes: -3

Sinatr
Sinatr

Reputation: 21979

1) Many markup extensions understand shortened syntax, there is no difference between {Binding Persons} and {Binding Path=Persons}. However, sometimes you must use full syntax.

One example would be to make own

public class ExceptionBinding : Binding
{
    public ExceptionBinding()
    {
        ValidationRules.Add(new ExceptionValidationRule());
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
    }
}

then you must use full syntax {l:ExceptionBinding Path=Persons}.

2) It depends. You don't have to use ObservableCollection<> if collection is not going to change after you bind to it. Creating List<>, filling it up and then binding to it will work pretty well.

You have to read about MVVM, because using it will simplify usage scenarios and makes many things more clear.

Upvotes: 2

Noctis
Noctis

Reputation: 11763

Mike covered what I wanted to say ...

In addition to the binding, you can also show different things in your bindings. Here's a tutorial I've wrote for the code project: Understanding SelectedValue, SelectedValuePath, SelectedItem & DisplayMemberPath + Demo

You can do mockups of your class with dummy data so you'll see a preview in your XAML designer in VS. MVVM light framework helps out and has some cool features as well. There are other frameworks, and you don't really need one for doing MVVM, but they help.

Other than that, I wish you good luck on your journey ... :) once you'll master it, it'll be fun ...

Upvotes: 1

Mike Eason
Mike Eason

Reputation: 9713

Question 1:

None, there is no difference. {Binding xyz} is the same as {Binding Path=xyz}, it's almost like a shortcut. But it can only be used on the first thing you write in your binding, for example, you cannot do this:

{Binding ElementName=myElement, xyz}

Instead, you would do this:

{Binding ElementName=myElement, Path=xyz}

Or even better:

{Binding xyz, ElementName=myElement}

Here's a related question.

Question 2:

What you have done is correct, your collection of people should be exposed as a Property, why? Because then you can bind to it.

There is no need for a static property in this scenario.

I would strongly suggest researching the MVVM Design Pattern. You can find a tutorial here

Upvotes: 4

Related Questions