2012-01-27 58 views
1

我有一个使用实体框架模型的WPF应用程序。其中一个实体是员工类型。该实体具有姓氏和名字等属性。但在我的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

您使用的属性更改事件? – Kevin 2012-01-27 20:32:34

回答

2

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

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

您的新房地产没有筹集这个活动,但是因为它是从LastNameFirstName计算出来的,当这两个变化时您需要提高PropertyChanged事件。

幸运的是EF会产生从那里你可以引发事件的部分方法与名称OnSomePropertyChanged每个属性的setter方法:

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

使用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(); 
    } 
} 
+2

你甚至不需要转换器,你可以使用绑定的stringformat选项 – 2012-01-27 23:23:19

+0

感谢Bob指出了这一点。我没有意识到它,它使解决方案更容易,因为它完全避免了任何代码。我相应地编辑了我的答案。 – Clemens 2012-01-28 06:45:15

+0

这将工作得很好,但在我的情况下,FullName属性将用于用户界面中的许多地方。 – Jerry 2012-01-28 19:10:00