簡體   English   中英

EF EntityObject 不更新關系的數據綁定

[英]EF EntityObject not updating databindings of relationships

我在我的應用程序中使用 EntityFramework、WPF 和 MVVM,但在更新 EntityObjects 之間關系的數據綁定時遇到了一些問題。 我能夠將我的問題縮小到只有幾行 XAML 並且我希望有人可以幫助我,因為我對 EF 和 MVVM 仍然不是很有信心。

無論如何,這里我們 go 和簡化的 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 個標簽來測試我的數據綁定。 使用 DatePicker 更改 File.SentDate 將數據綁定更新到最后的 Label 沒有問題。

現在 File 是 EntityObject 類型,並且具有 GUID 類型的 SenderId 屬性。 它還通過 Sender 屬性與我的聯系人有關系。 顯然,SenderId 是通過 Sender 關系與 File 相關的對應 Contact EntityObject 的 GUID。 一個文件只能有 1 個聯系人類型的發件人。

無論如何,發生的情況是,當我 select 另一個發件人使用 combobox 時,顯示 File.SenderId 屬性的 Label 得到正確更新。 但是,具有 File.Sender.Name 屬性的那個,即使用關系的那個沒有得到更新。

所以我猜想在 EF 中更新關系的數據綁定有一些特別之處。

有人可以提出解決方案嗎?

不幸的是,實體框架不會在關聯屬性更改時發出通知。 這就是您的綁定不起作用的原因。

該問題已報告給 Microsoft: http://connect.microsoft.com/VisualStudio/feedback/details/532257/entity-framework-navigation-properties-don-t-raise-the-propertychanged-event

WPF 應用程序框架 (WAF)BookLibrary示例應用程序顯示了另一種解決方法。 Book class 監聽 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");
}

如果您只是想要一個名稱,另一種解決方法是覆蓋 Sender 的 ToString() 並直接綁定到發件人。 這種解決方法很好,因為大多數時候我們將數據綁定到屬性的屬性時,我們這樣做是為了將 object 的“名稱”設置為屬性值。 如果您編輯 tt 文件以將部分添加到所有 class 定義,則此方法也適用於數據庫優先方法。

因此,您添加一個文件以包含您的實體的 ToString 擴展名,並在其中添加如下內容:

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

所以你可以數據綁定

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

現在數據綁定將檢測 Sender 是否更改,當它發生更改時,它將調用 ToString 以確定要顯示的內容。

另一方面,如果您需要綁定到另一個非標准屬性,您可能會遇到問題。 我確實記得成功使用 DataContext 和模板來解決它。 您綁定到 Sender 並使用 DataTemplate 來確定要顯示的內容。

看起來我已經找到了解決方案,盡管對我來說它更像是一種解決方法。 這不是我所期望的解決方案,但它有效。

XAML 還是和上面一樣,除了一件事。 我沒有綁定到 File.Sender.Name,而是像這樣綁定到 File.SenderName:

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

在這種情況下,SenderName 是 object 文件的屬性,我在部分 class 中添加了該文件,如下所示:

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 屬性。 而已。 奇跡般有效。 盡管我仍然不相信這是它應該工作的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM