我有一个使用实体框架模型的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
答案 0 :(得分:2)
WPF中的更改通知是使用INotifyPropertyChanged接口完成的。
它与Entity Framework一起开箱即用,因为生成的实体(通过默认的edmx模板)实现此接口,生成的属性设置器触发PropertyChanged
事件。
您的新酒店未提及此活动,但因为它是从LastName
和FirstName
计算的,当这两项更改时您需要举起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();
}
}