0

Following Problem: I've got a DataModel containing a list of objects and a reference to the selected object inside the List (among other things) Everything is working fine - if I select s.th. in the ListBox it is also available at the SelectedItem - if I change s.th. on the SelectedItem it gets updated in the whole DataModel.

..With one Exception though: The Content of the ListBox is not updated. I suspect it has something to do with the DataTemplate, because I can observe the following:

  • if I change the SelectedItem the List of items in the DataModel gets updated accordingly (checked on Debugger - also I always see the correct data on the selected item edit box)
  • The ListBox gets updated if I add an object from the list inside the DataModel, BUT also during this update I only get a new item in the ListBox the existing texts are not getting updated (so the List actually reflects the data from the DataModel)
  • If I reload the DataModel the whole ListBox gets rebuild and also the displayed Data is correct (so there is nothing wrong with the Binding source)

Update: New Information available about the exact problem

The Problem is actually some combination of Xsd2Code and ComplexType Extensions (in XSD). I don't think it's a bug in Xsd2Code, the generated Code looks fine.

The XSD file used

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="SampleRoot">
        <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="30">
                <xs:element name="SampleElement">
                    <xs:complexType>
                        <xs:complexContent>
                            <xs:extension base="SampleElement"/>
                        </xs:complexContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="SampleElement">
        <xs:attribute name="Name" type="xs:string" use="required"/>
    </xs:complexType>
</xs:schema>

The used DataModel (simplified, PropertyChanged is correctly implemented, classes SampleRootSampleElement and SampleRoot are generated by Xsd2Code):

public class DataModel : INotifyPropertyChanged
{
    public SampleRootSampleElement SelectedItem;
    public SampleRoot Root;
}

As for the XAML, nothing special here:

    <ListBox Height="211" HorizontalAlignment="Left" Margin="12,12,0,0" Name="listBoxNames" VerticalAlignment="Top" Width="189" ItemsSource="{Binding Root.SampleElement}" SelectedItem="{Binding SelectedItem}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <TextBox HorizontalAlignment="Left" Margin="12,229,0,0" Name="textBoxName" VerticalAlignment="Top" Width="189" Text="{Binding SelectedItem.Name}" />

This combination shows the described behaviour. To fix this behaviour, I can remove the Extension for SampleElement inside the XSD, which reduces the XSD to:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="SampleRoot">
        <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="30">
                <xs:element name="SampleElement" type="SampleElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="SampleElement">
        <xs:attribute name="Name" type="xs:string" use="required"/>
    </xs:complexType>
</xs:schema>

Everything else stays the same with the exception that there is no SampleRootSampleElement class generated (which was the Extension earlier). Instead SampleElement is directly used:

public class DataModel : INotifyPropertyChanged
{
    public SampleElement SelectedItem;
    public SampleRoot Root;
}

This few changes make everything working as expected - with the drawback that extensions can't be used. So what is wrong on the first approach in case I want to extend complex types?

Philipp Wendt
  • 2,538
  • 1
  • 15
  • 17
  • 1
    Is your underlying class i.e. where `Name` property resides implementing `INotifyPropertyChanged` interface? – Rohit Vats Feb 12 '14 at 11:13

1 Answers1

0

TextBlock value was not updated because of two possible but related issues:

  • Your Asset(don't know what is underlying type) class does not implement INotifyPropertyChanged interface.
  • If you have implemented PropertyChanged event handler - use it in Name setter:

public string Name 
{ 
    get
    {
        return this.name;
    }

    set
    {
        this.name = value;
        this.OnPropertyChanged("Name");
    }
}

After applying both suggestions you'll get your example working as expected.

Anatolii Gabuza
  • 6,184
  • 2
  • 36
  • 54
  • Actually the OnPropertyChanged is existing and being called. The problem seems to be that the PropertyChanged-Handler is set to null (so no Connection). The DataModel is btw generated by XSD2Code with DataBinding enabled, so it'd be confusing to provide everything. I try to recreate the issue in a stripped down example. – Philipp Wendt Feb 12 '14 at 12:44
  • 1
    @PhilippWendt So the problem is in XSD2Code generator. I've used your `xaml` with proper `Asset` class and it works as expected - value has being updated. – Anatolii Gabuza Feb 12 '14 at 13:46
  • You're right. Something is wrong if I use extensions in XSD. Not sure what though. As the problem basically is the same, I will update the Question. – Philipp Wendt Feb 13 '14 at 09:11