EF EntityObject не обновляет привязки данных отношений - PullRequest
2 голосов
/ 15 июля 2011

Я использую EntityFramework, WPF и MVVM в своем приложении и у меня возникли некоторые проблемы с обновлением привязки данных отношений между EntityObjects. Я смог уменьшить свою проблему до нескольких строк XAML, и я надеюсь, что кто-то может мне помочь, поскольку я все еще не очень уверен в EF и MVVM.

В любом случае, мы идем с упрощенным XAML:

    <DatePicker Grid.Row="2" Grid.Column="1" 
                    SelectedDate="{Binding Path=File.SentDate, 
StringFormat={}{0:dd/MM/yyyy}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                    VerticalAlignment="Center" IsEnabled="{Binding Path=IsEnabled}"/>

        <ComboBox Grid.Row="3" Grid.Column="1" ItemsSource="{Binding Contacts}" DisplayMemberPath="Name" 
                  SelectedItem="{Binding Path=File.Sender, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEditable="True"
                  VerticalAlignment="Center">
        </ComboBox>

        <Label Content="{Binding Path=File.SenderId}" Grid.Row="4"/>
        <Label Content="{Binding Path=File.Sender.Name}" Grid.Row="5"/>
        <Label Content="{Binding Path=File.SentDate}" Grid.Row="6"/>

Я использую последние 3 ярлыка для проверки привязки данных. Изменение File.SentDate с использованием DatePicker без проблем обновляет привязку данных до последней метки.

Теперь File имеет тип EntityObject и имеет свойство SenderId типа GUID. Он также имеет отношение к моим контактам через свойство отправителя. Обязательно, SenderId - это GUID соответствующего Contact EntityObject, который связан с File через отношение Sender. Файл может иметь только одного отправителя типа «Контакт».

В любом случае происходит следующее: когда я выбираю другого отправителя с помощью комбинированного списка, метка, отображающая свойство File.SenderId, корректно обновляется. Однако тот, у которого есть свойство File.Sender.Name, то есть тот, который использует отношение, не обновляется.

Так что я предполагаю, что есть что-то особенное в обновлении связей данных в EF.

Может кто-нибудь предложить решение этого вопроса?

Ответы [ 3 ]

1 голос
/ 16 июля 2011

К сожалению, Entity Framework не уведомляет об изменении свойства ассоциации.Вот почему ваше связывание не сработало.

О проблеме сообщили в Microsoft: http://connect.microsoft.com/VisualStudio/feedback/details/532257/entity-framework-navigation-properties-don-t-raise-the-propertychanged-event

Другой обходной путь показан на примере BookLibrary применение WPF Application Framework (WAF) .Класс Book прослушивает событие AssociationChanged и вызывает соответствующее событие PropertyChanged.

public Book()
{
    …
    LendToReference.AssociationChanged += LendToReferenceAssociationChanged;
}

private void LendToReferenceAssociationChanged(object sender, 
        CollectionChangeEventArgs e)
{
    // The navigation property LendTo doesn't support the PropertyChanged event. 
    // We have to raise it ourselves.
    OnPropertyChanged("LendTo");
}
0 голосов
/ 24 сентября 2014

Еще один обходной путь, если вам просто нужно имя, - переопределить ToString () для Отправителя и связать его непосредственно с отправителем.Этот обходной путь хорош, потому что большую часть времени, когда мы привязываем данные к свойству свойства, мы делаем это, чтобы получить «имя» объекта, установленное в качестве значения свойства.Также этот метод работает и для подхода «Сначала база данных», если вы редактируете tt-файлы, чтобы добавить частичное во все определения классов.

Таким образом, вы добавляете файл, содержащий расширения ToString ваших Entites, и в нем вы добавляете что-то вроде этого:1003 *

public partial Contacts 
{
    public override string ToString()
    {
        return Name;
    }
}

, так что вы можете привязать данные

<Label Content="{Binding Path=File.Sender}" Grid.Row="5"/>

Теперь привязка данных обнаружит, изменился ли Отправитель, и при этом вызовет ToString, чтобы определить, что отображать.

С другой стороны, если вам нужно привязать к другому нестандартному свойству, у вас могут возникнуть проблемы.Я помню, как успешно использовал DataContext и шаблоны, чтобы обойти это.Вы связываетесь с Sender и используете DataTemplate, чтобы определить, что отображать.

0 голосов
/ 15 июля 2011

Похоже, я нашел решение, хотя для меня это больше похоже на обходной путь. Это не решение, которое я ожидал, но это работает.

XAML все тот же, что и выше, за исключением одной вещи. Вместо привязки к File.Sender.Name, я привязываюсь к File.SenderName следующим образом:

<Label Content="{Binding Path=File.SenderName}" Grid.Row="4"/>

SenderName в этом случае является свойством объекта File, который я добавил в частичный класс, подобный этому:

public partial class File
{
        public string SenderName
        {
            get
            {
                if (this.Sender != null)
                {
                    return this.Sender.Name;
                }

                return string.Empty;
            }
        }
protected override void OnPropertyChanged(string property)
        {

            if (property == "SenderId")
            {
                OnPropertyChanged("SenderName");
            }
            base.OnPropertyChanged(property);
        }
}

Итак, что здесь происходит, если свойство SenderId изменяется, я говорю инфраструктуре также обновить свойство SenderName. Вот и все. Работает как шарм. Хотя я до сих пор не убежден, что так оно и должно работать.

...