简体   繁体   中英

Deserialization binding problem with nested custom objects

I have an application I am creating in WPF, using MVVM pattern. In this app, I have an ObservableCollection<> of Email objects. I have a Master-details form which displays the collection in a listbox, and the class properties 'Address', 'EType' and 'isPrimary' are displayed in a Textbox, combobox and checkbox, respectively.

The combobox has a List<> of EmailTypes as an ItemsSource, and the selected item is bound to the Type property of the SelectedItem in the ViewModel.

Everything works great, pretty easy. However, I want to serialize the ObservableCollection for undo purposes. This works OK too, using ISerializableSurrogate (method here ). With one exception:

The combobox will not bind to to the SelectedItem.EType property, at least not initially. Instead of the combobox showing the type when an email object is selected, as is the case with the pre-serialized version, the combobox is empty (unselected). If I manually select the type in the combobox, it will work, and update the Selected Emails type property. i Have to manually 'reset' the binding(?) between the two objects.

The Address ( a string) and CheckBox (a boolean) work fine. And the deserialized Email object DOES have the expected EType nested object coming out of the deserialize call; I can see it in the debugger while inspecting the locals.It's as if the binding doesnt recognize the deserialized version of an EType object as a valid Etype object...

Any ideas where exactly this is falling apart? I know there are some other ways of taking care of my undo requirement, but I really want to learn why this is not working...

FYI, I know that this is not a problem with the ObservableCollection, because I can create a new ObservableCollection, manually add an original Email object and a deserialized email object, and I have the same issue.

Here are my classes, grossly simplified:

A business object here:

[Serializable]
public class Email : INotifyPropertyChanged
{
    private int _id;
    private string _address;
    private emailType _eType;
    private bool isPrimary;

    public string Address 
    {
        get { return _address; }
        set 
        { 
            _address = value;
            onPropertyChanged(new PropertyChangedEventArgs("Address"));
        }
    }
    public EmailType EType 
    {
        get { return _eType; }
        set 
        { 
            _type = value;
            onPropertyChanged(new PropertyChangedEventArgs("EType"));
        }
    }
    public bool IsPrimary 
    {
        get { return _isPrimary; }
        set 
        { 
            _isPrimary = value;
            onPropertyChanged(new PropertyChangedEventArgs("IsPrimary"));
        }
    }

A lookup class here:

[Serializable]
public class emailType
{
    protected readonly int _id;
    protected String _name;

    public int Id
    {
        get { return _id; }
    }
    public String Name
    {
        get { return _name; }
    }
}

And the combobox in XAML:

<ComboBox Grid.Column="1" Grid.Row="3" Height="23" HorizontalAlignment="Left" Margin="3" Name="typeComboBox" VerticalAlignment="Top" Width="190" 
              ItemsSource="{Binding EmailTypes}" IsSynchronizedWithCurrentItem="False"   >
        <ComboBox.SelectedItem>
            <Binding Path="SelectedEmail.EType"  NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <local:NullValueRule></local:NullValueRule>
                </Binding.ValidationRules>
            </Binding>
        </ComboBox.SelectedItem>

    </ComboBox>

You will need to override the Equals method in the emailType class. Without doing so, the implementation that is inherited from object is used.

This implementation compares the object references. The deserialized object might have all the same properties however it os a different object and will not be 'equal'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM