C# – Caliburn Micro Datagrid Binding

bindingccaliburn.microdatagridwpf

I'm using Caliburn Micro framework in a WPF application and I need to bind a collection to ItemsSource of a DatGrid.
Please consider below code:

Class

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ObservableCollection<Subject> Subjects;
}

public class Subject
{
    public string Title{ get; set; }
}

View Model

public class PersonViewModel : Screen
{
    private Person _person;

    public Person Person
    {
        get { return _person; }
        set
        {
            _person = value;
            NotifyOfPropertyChange(() => Person);
            NotifyOfPropertyChange(() => CanSave);
        }
    }
    ....
}

View

<UserControl x:Class="CalCompose.ViewModels.PersonView" ...ommited... >
    <Grid Margin="0">
        <TextBox x:Name="Person_Id" HorizontalAlignment="Left" Height="23" Margin="10,52,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <TextBox x:Name="Person_Name" HorizontalAlignment="Left" Height="23" Margin="10,90,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <DataGrid ItemsSource="{Binding Person_Subjects}" Margin="10,177,0,0"></DataGrid>     
    </Grid>
</UserControl>

Problem 1:
When I run the application the TextBoxes are getting right values, but the data grid haven't populated.
Here i'm using deep property binding technique using convention "ClassName_PropertyName".

Problem 2
When I change the value of 'Name' property the
NotifyOfPropertyChange(() => Person) is never called. I would like to call the guard method when the text changes in the Name field.

Can anyone suggest me a simple solution to overcome this issues?
Thanks in advance.

Best Answer

Implement PropertyChangedBase on the Person class, then for Name we can write

private string name;
public string Name
{
    get { return name; }
    set
    {
        if (name == value)
            return;
        name = value;
        NotifyOfPropertyChange(() => Name);
    }
}

For the binding to the DataGrid, dont use the "deep binding", merely use

<DataGrid ItemsSource="{Binding Person.Subjects}" ...

I hope this helps.

Related Topic