Как я могу получить свой частичный класс для обновления - PullRequest
1 голос
/ 28 января 2012

У меня есть приложение WPF, которое использует Entity Framework Model.Одна из сущностей - это тип сотрудника.Эта сущность имеет свойства LastName и FirstName среди других.Но в моем xaml я хочу отобразить полное имя в моей DataGrid.Поэтому я создал этот частичный класс для возврата полного имени и отображаю это свойство в 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 обновляются?Как мне исправить это?

Вот моя форма редактирования 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 ]

2 голосов
/ 28 января 2012

Уведомление об изменении в 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 голос
/ 28 января 2012

Использование 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();
    }
}
...