如何让我的Partial Class进行更新

时间:2012-01-27 20:18:47

标签: wpf entity-framework partial-classes

我有一个使用实体框架模型的WPF应用程序。其中一个实体是员工类型。此实体具有LastName和FirstName属性等。但在我的xaml中,我想在我的DataGrid中显示一个全名。所以我创建了这个Partial Class来返回全名,我在DataGrid中显示了这个属性。这非常有效。 FullName按预期显示在DataGrid中。

public partial class Employee
{
    public string FullName
    {
        get { return LastName.Trim() + ", " + FirstName.Trim(); }
    }
}

我遇到的问题是我的编辑表单包含绑定到LastName和FirstName属性的文本框。当我更新诸如CompanyName,LastName,FirstName,HireDate等的值时... DataGrid中所有已更改的列都会正确更新,但FullName属性不会更新。

为什么我的FullName分部类不会更新,而其余的DataGrid属性会更新?我该如何纠正?

这是我的editform xaml。

<TextBox Grid.Column="1" Name="txtCompany" Text="{Binding SelectedEmployee.Company, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Grid.Column="1" Name="txtFirstName" Text="{Binding SelectedEmployee.FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Grid.Column="1" Name="txtLastName" Text="{Binding SelectedEmployee.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="1" Name="txtFullName" Grid.Row="2"  Margin="2" Text="{Binding SelectedEmployee.FullName" />    -- Also show as column in DataGrid

2 个答案:

答案 0 :(得分:2)

WPF中的更改通知是使用INotifyPropertyChanged接口完成的。

它与Entity Framework一起开箱即用,因为生成的实体(通过默认的edmx模板)实现此接口,生成的属性设置器触发PropertyChanged事件。

您的新酒店未提及此活动,但因为它是从LastNameFirstName计算的,当这两项更改时您需要举起PropertyChanged活动。

幸运的是,EF将为每个属性设置器生成一个部分方法,名称为OnSomePropertyChanged,您可以在此处引发事件:

public partial class Employee
{
    public string FullName
    {
        get { return LastName.Trim() + ", " + FirstName.Trim(); }
    }

    partial void OnLastNameChanged()
    {
         base.OnPropertyChanged("FullName");
    }

    partial void OnFirstNameChanged()
    {
         base.OnPropertyChanged("FullName");
    }
}

答案 1 :(得分:1)

MultiBinding与适当的StringFormat一起使用可以避免任何额外的代码,并且将是一个更通用的解决方案,因为它不依赖于EF所做的事情。请注意带有前导{}的格式字符串的有趣表示法,它在XAML中的字符串中启用花括号:

<TextBlock Name="fullNameTextBlock">
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{1}, {0}">
            <Binding Path="FirstName"/>
            <Binding Path="LastName"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

有点复杂,但更通用的方法是将MultiBinding与IMultiValueConverter结合使用。您可以像这样创建一个MultiBinding:

<TextBlock Name="fullNameTextBlock">
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource FullNameConverter}">
            <Binding Path="FirstName"/>
            <Binding Path="LastName"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

转换器基本上会是这样的:

public class FullNameConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((string)values[1]).Trim() + ", " + ((string)values[0]).Trim();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}