【问题标题】:Bind ObservableCollection to ItemsControls or ListView doesn't working将 ObservableCollection 绑定到 ItemsControls 或 ListView 不起作用
【发布时间】:2016-12-07 15:11:19
【问题描述】:

在一个 UWP 项目中,我有:1 个页面、1 个用户控件和 1 个视图模型。

该页面包含一个拆分视图,其中用户控件加载到窗格中:

<SplitView.Pane>
    <local:MyUserControl />
</SplitView.Pane>

页面和用户控件都具有相同的数据上下文:视图模型(称为 MyPageViewModel)。 ViewModel 有一个 ObservableCollection 对象,例如:

public ObservableCollection<MyModel> Commands { get; set; }

在按钮单击事件的页面代码隐藏中,我创建了一个列表:

List<MyModel> ListCommands;

在我加载一些数据的地方,然后我直接从 ViewModel 调用一个方法,例如:

(this.DataContext as MyPageViewModel).Load(listCommands);

Load 是 View Model 中定义的方法,它填充 ObservableCollection:

public void Load(List<MyModel> commands)
    {
        Commands = new ObservableCollection<MyModel>(commands);
    }

这个 ObservableCollection 在运行时加载成功,但是用户控件中的 ItemsControl 不显示数据(好像没有通知用户界面发生了变化),在用户控件代码中:

<UserControl.DataContext>
    <ViewModels:RestaurantDetailsViewModel />
</UserControl.DataContext>

...

<ItemsControl ItemsSource="{Binding Commands}"
                  Grid.Row="1" />

ItemsControl 保持为空(我使用 DataTemplate 来显示内部 MyModel 属性)。我也用 ListView 测试过,但结果是一样的。

注意:我的视图模型继承自实现 INotifyPropertyChanged 的​​自定义类:

public class MyPageViewModel : BindabelBase

public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public void Set<T>(ref T storage, T value, [CallerMemberName()]string propertyName = null)
    {
        if (!object.Equals(storage, value))
        {
            storage = value;
            this.RaisePropertyChanged(propertyName);
        }
    }
}

【问题讨论】:

  • ViewModels INotifyProperty 实现怎么样?
  • 抱歉,我编辑了这个遗漏的细节。
  • 好的,所以你有 INotifyImplemented,但没有使用 ;) 尝试 - private ObservableCollection _commands;公共 ObservableCollection 命令 { ger {return _commands;} set {_commnads = value; RaisePropertyChanged("命令"); }
  • 是的,我没有提到,但我已经尝试过使用 INotify : private ObservableCollection _commands;公共 ObservableCollection CommandsToPay { get { return _commands; } 设置 { _commands = 值; RaisePropertyChanged("CommandsToPay");我在 set 中放置了一个断点,它正确通过但 UI 不在乎。
  • 页面和用户控件怎么会有相同的上下文?您的用户控件似乎正在创建视图模型的新实例。如果它们不同,则您正在填充页面的 vm 集合,但呈现用户控件的 vm 集合 - 这不会改变。

标签: uwp uwp-xaml


【解决方案1】:

感谢所有快速回答,问题已解决。

我的错误是重新声明了页面和用户控件的 DataContext tat 创建了 ViewModel 的新实例(= 页面和用户控件的数据上下文不同,两个不同的实例)。

解决方案是向用户控件指示页面的数据上下文,如下所示:

<local:MyUserControl DataContext="{Binding DataContext, ElementName=CommandesPage}" />

其中 CommandesPage 是页面的名称。

【讨论】:

    猜你喜欢
    • 2012-05-26
    • 2018-05-21
    • 2016-08-05
    • 2017-09-29
    • 1970-01-01
    • 2015-09-02
    • 2012-12-01
    相关资源
    最近更新 更多