【问题标题】:why is my Listview ItemsSource null (uwp app c#)为什么我的 Listview ItemsSource 为空(uwp app c#)
【发布时间】:2017-05-12 07:42:57
【问题描述】:

我正在尝试将 ViewModel 中的 List 绑定到 Page 中的 ListView,但我无法让它工作,尽管列表中填充了值,但 ItemsSource 始终为 null。

这就是我设置整个事情的方式。

这些属性被添加到我的 xaml 中的页面标记

xmlns:viewmodels ="using:TimeMachine3.ViewModels"
d:DataContext="{d:DesignInstance viewmodels:MasterViewModel}"

我的 ListView 被定义为

<ListView x:Name="lstMainMaster" ItemsSource="{Binding MyList}" SelectionChanged="lstMainMaster_SelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{x:Bind Name}"/>
                    <TextBlock Text="{x:Bind Number}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

在我的 master.cs(页面代码)中有

    private ViewModels.MasterViewModel viewmodel;

    //constructor
    public master()
    {
        this.InitializeComponent();
        this.Loaded += Master_Loaded;
    }

    private void Master_Loaded(object sender, RoutedEventArgs e)
    {
        viewmodel = new ViewModels.MasterViewModel();
        viewmodel.populate();
    }

在 masterViewmodel(页面的视图模型)中我有这段代码

    private ObservableCollection<Month> _myList;
    public ObservableCollection<Month> MyList{ get {return _myList; } }

    public void Populate()
    {
        _myList = new ObservableCollection<Month>(DataBase.GetMonths(2017));
    }

【问题讨论】:

  • 你在哪里用值填充你的列表,你能提供一些代码吗?
  • 我已经用更多代码编辑了我的问题,以展示它是如何完成的。 viewModel 在 Page.Loaded 事件处理程序中创建。创建后,在视图模型上调用 Populate()。在 populate() 我填充 List_myList 绑定属性 List MyList 在它的 get 语句中返回

标签: c# xaml listview uwp view-model-pattern


【解决方案1】:

它为空,因为您在加载视图后更改了MyList 指向的引用,并且没有通知视图更改(通过INotifyPropertyChanged)。因此,视图不知道它需要刷新绑定。

public void Populate()
{
    _myList = new ObservableCollection<Month>(DataBase.GetMonths(2017));
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyList)));
}

或等价物。

【讨论】:

  • 别担心。我们都去过那里:)
  • 我通过调用(在视图模型中)PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyList")); 实现了 INotifyChanged更改 List 属性后。然后我在视图中订阅 PropertyChanged 并重置 ItemsSource。这真的是正确的做法吗?或者有什么神奇的技巧可以让它更平滑?
  • 更安全的方法是向 MyList 添加一个 setter,它会引发事件,然后执行 MyList = new ...,而不是直接访问支持字段。
  • 如果你要经常做这种事情(我假设你是),那么创建一个视图模型基类可能是要走的路,所以你可以打电话给@987654325 @ 或类似名称。
【解决方案2】:

我刚刚意识到,如果我的 DataContext 设置正确,我不必实现 InotifyChanged 接口。

我改变了数据上下文的设置方式

xmlns:viewmodels ="using:TimeMachine3.ViewModels"
enter code here`d:DataContext="{d:DesignInstance viewmodels:MasterViewModel}"

<Page
...
xmlns:viewmodels ="using:TimeMachine3.ViewModels"
.../>
<Page.DataContext>
   <viewmodels:MasterViewModel>
</Page.DataContext>

现在 itemssource 将在调用 InitializeComponent() 后立即设置,如果我的列表被更改,那么我的 ListView 将更新而无需添加更多代码(我什至不必实现 INotifyChanged)

【讨论】:

    猜你喜欢
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 2017-08-06
    • 2014-02-26
    相关资源
    最近更新 更多