Hoffma
Hoffma

Reputation: 136

Binding the TextBlock of a Listview's GridView's DataGridCell

I've got an ObservableCollection of model objects that I'm attempting to display in the DataGridCells of a GridView in a ListView. For this simplified example, let's say that my model objects all have "MyString," and that I'm attempting to show "MyString" in a TextBlock inside of each row's DataGridCell.

As the ObservableCollection adds or removes these model objects, the ListView shows the correct number of rows, however the individual cells are empty. How do I properly bind them? Should I be using DataContext or ItemSource, and if so, where? Here's a single-column example of one such binding attempt.

<ListView ItemsSource="{Binding MyObservableCollection}">
    <ListView.View>
        <GridView>
            <GridViewColumn>
                <GridViewColumnHeader Content="My String Data" />
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <DataGridCell>
                            <TextBlock Text="{Binding Path=MyString}">
                            </TextBlock>
                        </DataGridCell>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

EDIT: Per Michal Ciechan, I've implemented INotifyPropertyChanged on my model class, but it didn't seem to change anything. I won't actually be changing the fields on these objects once they're in the collection, however, so this may not be the right approach. Here's some more example code.

The Model:

public class MyModel : INotifyPropertyChanged
{
    public string MyString;
    public event PropertyChangedEventHandler PropertyChanged;
}

The ViewModel:

ObservableCollection<MyModel> MyObservableCollection = new ObservableCollection<MyModel>();

public void AddModelToCollection()
{
    MyModel mm = new MyModel();
    mm.MyString = "HELLO WORLD";
    MyObservableCollection.Add(mm);
}

Upvotes: 0

Views: 121

Answers (2)

user1228
user1228

Reputation:

public string MyString; is a field, not a property. You can't bind to fields. You can only bind to properties.

private string _myString;
public string MyString
{
    get
    {
        return _myString;
    }
    set
    {
        _myString = value;
        OnPropertyChanged("MyString");
    }
}

I'll leave the implementation of OnPropertyChanged to you.

To clarify

This is a PROPERTY:

public string DERP { get; set; } 

Notice it has a getter and a setter. The compiler turns this into two methods, one for getting the value and one for setting it.

This is a FIELD:

public string HERP;

Notice, it doesn't have a getter or a setter. It is just a pointer to a value on the stack.

Here comes the important bit:

In WPF, Bindings do NOT WORK with FIELDS. They only work with PROPERTIES

So setting the value of a field prior to attempting to bind against it matters not. The Binding won't be looking for fields, and therefore won't see it.

Upvotes: 2

Michal Ciechan
Michal Ciechan

Reputation: 13898

Will is right, your Model class needs to have MyString as a Property rather than field.

What is the difference between a Field and a Property in C#?

WPF - Binding - Binding Source

You can bind to public properties, sub-properties, as well as indexers, of any common language runtime (CLR) object. The binding engine uses CLR reflection to get the values of the properties. Alternatively, objects that implement ICustomTypeDescriptor or have a registered TypeDescriptionProvider also work with the binding engine. For more information about how to implement a class that can serve as a binding source, see Implementing a Class for the Binding Source later in this topic.

public class MyModel : INotifyPropertyChanged
{
    private string _myString;
    public string MyString
    {
        get
        {
            return _myString;
        }
        set
        {
            _myString = value;
            OnPropertyChanged("MyString");
        }
    }
}

Upvotes: 1

Related Questions