外键关系"通过电线" (如何对它们进行数据绑定?)

时间:2012-12-10 16:41:13

标签: .net wpf wcf web-services data-binding

场景:需要从Web服务收集对象集合并将其呈现在GUI中。该对象包含对另一个对象(外键)的引用,我也需要表示这些相关对象。

我有两种可能的选择,分别有各自的缺点:

  1. 发送“通过电线”整个相关对象。
  2. 只发送外键并检索查询另一个集合(之前存储在本地)的相关对象
  3. 第一个选项直接进行数据绑定(我在客户端使用WPF),虽然它在通信中引入了很大的开销(特别是如果相同的相关对象出现很多次)。因此,似乎不是要走的路。

    第二个选项实现了更小的消息,看起来就像是要走的路。 但是,我找不到对此相关对象执行数据绑定的方法

    让我用一个例子来澄清这个问题:

    对象 - >房间||相关对象 - >建筑||本地存储的集合 - >建筑物

    来自Web服务的消息包含房间属性(比如说“name”,“size”......)和“BuildingId”。我希望能够在UI中显示(自动通过数据绑定)来自建筑物的信息,而不仅仅是“BuildingId”。因此,我必须查询“Buldings”集合以获取正确的Bui​​lding Object,然后使用其属性来填充UI ,这似乎是合乎逻辑的。

    所以,我的问题是:

    1. 如何通过WPF中的数据绑定实现这一目标?我想有一种自动实现方法。不存在吗?
    2. 我缺少任何潜在的概念(与数据绑定有关)吗?我是.NET Stack的新手,所以也许这比我看起来更容易!
    3. 谢谢你们! ;)

      P.S。:任何可以指向正确方向的文件/链接都将受到高度赞赏;)

2 个答案:

答案 0 :(得分:1)

我会在Room对象上有一个名为Building的属性,它最初可以为空(null),但在加载构建对象时稍后设置。您的会议室对象应该实现INotifyPropertyChanged,这将在最终加载对象时通知UI并导致所有绑定刷新。

示例INotifyPropertyChanged实现:

private bool _Active;
public bool Active
{
    get { return _Active; }
    set
    {
        if (_Active == value)
            return;

        _Active = value;
        OnPropertyChanged("Active");
    }
}

#region PropertyChanged Implementation

        // Code Below Copied From : http://www.codeproject.com/KB/cs/PropertyNotifyPart1.aspx
        /// <summary>
        /// Raises the <see cref="E:PropertyChanged"/> event.
        /// </summary>
        /// <param name="propertyName">
        /// Name of the property that changed.
        /// </param>
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
            OnPropertyChanged(e);
        }

        /// <summary>
        /// Raises the <see cref="E:PropertyChanged"/> event.
        /// </summary>
        /// <param name="e">
        /// The <see cref="PropertyChangedEventArgs"/> instance
        /// containing the event data.
        /// </param>
        protected void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler temp = this.PropertyChanged;
            if (null != temp)
                temp(this, e);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler temp = this.PropertyChanged;
            if (null != temp)
                temp(sender, e);
        }

        #endregion

答案 1 :(得分:1)

尝试将您的两个选项与.Net / WPF世界中的典型方法联系起来(以相反的顺序):

方法2: Model-View-ViewModel方法(MVVM)可能是一种方法。您的DTO旨在使用WCF(模型)优化消息传递。 MVVM原则建议您不要因为数据绑定等问题而污染它们。一个单独的类ViewModel对此负责,并且还可以使用缓存查找等管理诸如将原始标识符(例如BuildingId)映射到对象的可绑定表示之类的问题。而不是绑定到您的DTO,然后您的WPF视图绑定到ViewModel

如果您想要使用此选项,请先了解the MVVM concept,然后您可能需要考虑使用辅助工具。 (我发现Caliburn Micro非常出色,但有一些对于WPF而言

方法1: 这是更简单的方法,意味着您编写WCF服务,以便它从服务器向客户端提供预制的ViewModel(即您的DTO和ViewModel是相同的)。正如您已经观察到的那样,由于构建ViewModel的责任是在服务器上完成的,因此您可能会遇到传输冗余数据的问题。这种方法还意味着客户端和服务器紧密耦合 - 每个DTO / ViewModel都设计用于特定的视图。

最终,最佳方法取决于您的应用程序的要求。如果您正在寻找一种简单的方法,您不需要担心某些冗余数据通信,并且只是想尽快找到解决方案,那么方法1可能更可取。

但是,如果您需要服务其他客户端,或者由于其他原因避免耦合客户端和服务器或者需要高效通信很重要,则应考虑MVVM方法。