【问题标题】:Caliburn.Micro NotifyOfPropertyChange different way of UI UpdateCaliburn.Micro NotifyOfPropertyChange UI 更新的不同方式
【发布时间】:2020-01-30 18:50:04
【问题描述】:

有人可以向我解释为什么 ItemsControl 只在我通过 Caliburn.Micro 框架(按钮 x:Name="LoadView")手动重新激活我的视图时更新我的​​ UI。

为什么这种方式实际上会立即更新我的 UI?

 Data = new BindableCollection<DataModel>
        (await dataAccess.Starter(progress, cts.Token).ConfigureAwait(true));

我理解错了什么? 编辑:

    private static BindableCollection<DataModel> _IDirectorys;

没有静态它根本不会更新。

    private static BindableCollection<DataModel> _IDirectorys;

    public BindableCollection<DataModel> Data
    {
        get
        {
            return _IDirectorys;
        }
        set
        {
            _IDirectorys = value;
            NotifyOfPropertyChange(() => Data);
        }
    }


    public async Task StartScan()
    {
        DataAccess dataAccess = new DataAccess();

        _IDirectorys = new BindableCollection<DataModel>
            (await dataAccess.Starter(progress, cts.Token).ConfigureAwait(true));
    }


<ItemsControl ItemsSource="{Binding Data, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}">

【问题讨论】:

  • 看来BindableCollection 不会通知属性在添加/删除时更改,使用ObservableCollection&lt;T&gt; 可能是解决方案,它会发布集合更改事件
  • 刚刚尝试过 ObservableCollection 并且它根本没有更新它。虽然当我声明 Data 而不是 _IDirectorys 它会立即更新
  • 编辑:忘了静态,有了它,效果和BindableCollection一样

标签: c# wpf caliburn.micro


【解决方案1】:

首先,非静态属性的支持字段不能是静态的。从 _IDirectorys 中删除 static 修饰符。

然后,当您在 StartScan 中创建新集合时,将其分配给属性,而不是支持字段。否则不会调用NotifyOfPropertyChange

public async Task StartScan()
{
    DataAccess dataAccess = new DataAccess();

    Data = new BindableCollection<DataModel>(await dataAccess.Starter(progress, cts.Token));
}

请注意,当您只创建新集合实例时,您既不需要 BindableCollection 也不需要 ObservableCollection,但从不向现有集合添加或删除元素。

所以这也应该有效:

private IEnumerable<DataModel> data;

public IEnumerable<DataModel> Data
{
    get => data;
    set
    {
        data = value;
        NotifyOfPropertyChange(() => Data);
    }
}

public async Task StartScan()
{
    DataAccess dataAccess = new DataAccess();

    Data = await dataAccess.Starter(progress, cts.Token);
}

最后但同样重要的是,在 ItemsSource Binding 上设置 UpdateSourceTriggerNotifyOnSourceUpdated 是没有意义的。这就足够了:

<ItemsControl ItemsSource="{Binding Data}">

【讨论】:

  • 感谢您的澄清,我按照您的建议实现了它,但我保留了 BindableCollection,因为我将来必须添加/删除东西。我的问题仍未得到解答。 “不立即更新”背后的原因是什么?
  • 如前所述,您使用的是 _IDirectorys = new BindableCollection&lt;DataModel&gt;() 而不是 Data = new BindableCollection&lt;DataModel&gt;()。前者不调用 NotifyOfPropertyChange。
  • 知道了,谢谢。不知道它不会调用 NotifyOfPropertyChange。
  • NotifyOfPropertyChange 调用在属性设置器中。如果不设置属性,显然不会被调用。
猜你喜欢
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 2010-10-18
相关资源
最近更新 更多