【问题标题】:Correct way to bind IEnumerable MVVM property that isn't an observable collection绑定不是可观察集合的 IEnumerable MVVM 属性的正确方法
【发布时间】:2013-07-22 12:48:47
【问题描述】:

假设我有这个域实体:

public class Foo
{
    public string Name { get; set; }
    public IEnumerable<Bar> Bars { get; set; }
}

现在假设我需要将 Bars 属性绑定到 WPF/MVVM 应用程序中的数据网格。通知 Bars 属性更改的视图的适当方法是什么?我看到了几个选项:

  1. 将 Bars 更改为 ObservableCollection
  2. 在视图模型上创建一个新属性,即作为真实 Bars 副本的 ObservableCollection。
  3. 刷新整个视图
  4. 别的/更好的?

我可以做 #1,但我不喜欢视图需要导致域实体发生变化。

数字 2 看起来不错,但有点 hackish。

3 号似乎效率低下。

最好的方法是什么?

编辑

为了完整起见,根据 Simon 的回答,我这样做了:

    public Foo SelectedFoo
    {
        get { return _selectedFoo; }
        set
        {
            _selectedFoo = value;
            this.NotifyPropertyChanged(() => this.Foo);

            _bars = new ObservableCollection<Bar>();
            if (_selectedFoo.Bars != null) { _bars.AddRange(_selectedFoo.Bars); }
            this.NotifyPropertyChanged(() => this.Bars);
        }
    }

    private ObservableCollection<Bar> _bars;

    public ObservableCollection<Bar> Bars
    {
        get { return _bars; }
    }

【问题讨论】:

  • 如果您知道它何时发生变化,只需在此处提出 PropertyChanged("Bars") 即可。如果不是,n.2 是正确的选择。
  • 我实际上在发布这个问题之前尝试过,但它没有用。也许我还有其他问题……
  • 我实际上会为FooBar 创建一个单独的视图模型并使用这些视图模型...
  • @newStackExchangeInstance 我刚刚尝试了PropertyChanged("Foo") 并且成功了。 Foo 并没有真正改变,但它导致 Bars 属性被识别为已更改。不确定这是否是好的做法。
  • @BobHorn 这不是“好的做法”,但它确实有效。想象一下,如果您的 Bars 包含一千个条目并且 Name 属性已更改。在Foo 上触发更改将导致在不需要时重新评估NameBars。一旦您的模型变得复杂,它就会变得越来越复杂。

标签: c# wpf mvvm


【解决方案1】:

在最佳实践中,您的视图不应直接绑定到您的模型:这就是您的视图模型的用途。理想情况下,您希望 #2 实现最大分离,并在适当时将更改同步回模型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多