-2

I can't seem to figure out what I should/should not be doing with my binding. I have a WPF window that uses two way binding for a nested object. Primary object is Client the client object has Residential and Mailing addresses which are of type Address objects. I can save the client object without issue but when it attempts to save the address objects they are either null or I have to create them by "newing" them up before the save. I assumed with using databinding that the nested object would be populated without having to do anything "special" aka not have to new them up just allow the binding do the work? Am I doing something wrong or am I expecting it to do too much for me?

In summary the object looks like this

public class Client : People
{
    public int ClientID { get; set; }
    public int? ResidentialAddressID { get; set; }
    [ForeignKey("ResidentialAddressID")]
    public virtual Address ResidentialAddress { get; set; }
    public int? MailingAddressID { get; set; }
    [ForeignKey("MailingAddressID")]
    public virtual Address MailingAddress { get; set; }

}
[Table("bhs.Addresses")]
public class Address
{
    public int AddressID { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public int? StateID { get; set; }
    public State State { get; set; }
    public string ZipCode { get; set; }
}

Tables looks like this

People ->
PeopleID
FirstName
MiddleName
LastName
DateOfBirth
SocialSecurityNumber
Gender

Client -> 
ClientID
PeopleID
ResidentialAddressID
MailingAddressID


Addresses->
AddressID
Line1
Line2
City
StateID
ZipCode

And the binding looks like so.

    <Label Content="First Name:" Grid.Column="0" Margin="0,1,0,0" Grid.Row="0" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <TextBox Grid.Column="1" Text="{Binding FirstName}" x:Name="txtFirstName" Margin="5,5,5,5" Grid.Row="0" TextWrapping="Wrap" />
    <Label Content="Middle Name:" Grid.Column="0" Margin="0,1,0,0" Grid.Row="1" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <TextBox Grid.Column="1" x:Name="txtMiddleName" Margin="5,5,5,5" Grid.Row="1" TextWrapping="Wrap" Text="{Binding MiddleName}" />
    <Label Content="Last Name:" Grid.Column="0" Grid.Row="2" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <TextBox Grid.Column="1" x:Name="txtLastName" Margin="5,5,5,5" Grid.Row="2" TextWrapping="Wrap" Text="{Binding LastName}" />
    <Label Content="Date Of Birth:" Grid.Column="0" Grid.Row="3" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <DatePicker Grid.Column="1" x:Name="datDateOfBirth" Margin="5,5,5,5" Grid.Row="3" SelectedDate="{Binding DateOfBirth}"/>
    <Label Content="Social Security Number:" Grid.Column="0" Grid.Row="4" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <xctk:MaskedTextBox x:Name="txtSocialSecurityNumber" Text="{Binding SocialSecurityNumber}" Margin="5,5,5,5"  Grid.Column="1" Grid.Row="4" TextWrapping="Wrap" ClipboardMaskFormat="ExcludePromptAndLiterals" IncludeLiteralsInValue="False" Mask="000-00-0000"/>
    <Label Content="Gender:" Grid.Column="0" Grid.Row="5" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <ComboBox Grid.Column="1" x:Name="cboGender" Grid.Row="5" Margin="5,5,5,5" SelectedValue="{Binding Gender}" />
    <Label Content="Residential Address:" Grid.Column="2" Margin="0,1,0,0" Grid.Row="2" Foreground="White" HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>
    <TextBox Grid.Column="3" Text="{Binding ResidentialAddress.Line1}" Margin="5,5,5,5" Grid.Row="0" TextWrapping="Wrap"/>           
    <TextBox Grid.Column="3" Text="{Binding ResidentialAddress.Line2}" Margin="5,5,5,5" Grid.Row="1" TextWrapping="Wrap" />
    <TextBox Grid.Column="3" Text="{Binding ResidentialAddress.City}" Margin="5,5,5,5" Grid.Row="2" TextWrapping="Wrap" />
    <ComboBox Grid.Column="3" SelectedValue="{Binding ResidentialAddress.State}" Margin="5,5,5,5" Grid.Row="3"/>
    <TextBox Grid.Column="3" Text="{Binding ResidentialAddress.Zip}" Margin="5,5,5,5" Grid.Row="4" TextWrapping="Wrap" />

Any help is extremely appreciated.

1 Answers1

1

You do have to initialize objects.

{Binding FirstName}

Works because you are setting this attribute to something.

{Binding ResidentialAddress.City}

Does not because ResidentialAddress doesn't exist, and so you can't access a field within it. WPF can't know it needs to initialize your object, and which constructor to use.

One thing you can do to get what you want is:

private Address _MailingAddress;
[ForeignKey("MailingAddressID")]
public virtual Address MailingAddress 
{
    get
    {
        return _MailingAddress ?? (_MailingAddress = new Address());
    }
    set
    {
        _MailingAddress = value;
    }
}

So that your object gets initialized the first time it is accessed, if it is null. Otherwise you can "new it up" as you say in the constructor.

Benoit Dufresne
  • 318
  • 3
  • 9