空引用异常实体framewwork绑定到WPF窗口[重复]

时间:2021-07-12 02:15:47

This question already has an answer here:

这个问题在这里已有答案:

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?

我似乎无法弄清楚我应该/不应该对我的绑定做什么。我有一个WPF窗口,它使用嵌套对象的双向绑定。主要对象是Client,客户端对象具有住宅和邮件地址,其类型为Address对象。我可以毫无问题地保存客户端对象,但是当它试图保存地址对象时,它们是空的,或者我必须通过在保存之前“新”它们来创建它们。我假设使用数据绑定,嵌套对象将被填充,而不必做任何“特殊”,也就是不必新建它们只是允许绑定做工作?我做错了什么还是我希望它对我做得太多?

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 个解决方案

#1


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.

不是因为ResidentialAddress不存在,因此您无法访问其中的字段。 WPF无法知道它需要初始化您的对象,以及使用哪个构造函数。

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.

这样你的对象在第一次被访问时就被初始化了,如果它是null的话。否则你可以像在构造函数中所说的那样“新建它”。

#1


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.

不是因为ResidentialAddress不存在,因此您无法访问其中的字段。 WPF无法知道它需要初始化您的对象,以及使用哪个构造函数。

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.

这样你的对象在第一次被访问时就被初始化了,如果它是null的话。否则你可以像在构造函数中所说的那样“新建它”。