WPF-DataGrid不显示列表

时间:2019-08-20 15:31:46

标签: c# wpf datagrid

我的目标是在数据网格中输出列表,但这不起作用,并且数据网格为空。

我试图以其他方式显示列表,但确实做到了(但我不记得它是什么),并且可以正常工作,除了它不在数据网格中,而只是在数据中。我已经改变了一些东西,但是那时候它到了尽头并得到显示。

Mainwindow中的ViewModel:

public class ViewModel
        {
            public List<ssearch> Items { get; set; }

            private static ViewModel _instance = new ViewModel();
            public static ViewModel Instance { get { return _instance; } }
        }

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel();

            //For simplicity, let's say this window opens right away
            var Mdata = new MDataWindow { DataContext = DataContext };
            Mdata.Show();
        }

其他用于显示数据的窗口:

string searchParam = "status = 1"; 
        public MDataWindow()
        {
            InitializeComponent();
        }

        private void AButton_Click(object sender, RoutedEventArgs e)
        {
            MainWindow.ViewModel.Instance.Items = Search(searchParam);
        }

public List<ssearch> Search(string where)
        {
            {
                 //Lots of stuff going on here
            }
            return returnList;
        }

在WPF中:

<Window x:Class="WPFClient.MDataWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFClient"
        mc:Ignorable="d"
        Title="MDataWindow" Height="Auto" Width="Auto">
    <StackPanel>
        <Button x:Name="AButton" Click="AButton_Click" Content="Load" />

        <DataGrid ItemsSource="{Binding Items}" />
    </StackPanel>
</Window>

我不知道错误在哪里,并尝试在不破坏错误源的情况下尽可能地减少代码。当我按下“加载”按钮时,Datagrid保持为空。

编辑: 在将列表传递给ViewModel之前,我尝试将其转换为observableColletion,但这没有用。我正在使用一个库,我不确定该如何将它与observableCollection一起使用,因此我转换了它而不是立即使用它:

VM: public ObservableCollection<Product> Items { get; set; }

数据窗口:

List<Product> pp = Search_Products(searchParam);
var oc = new ObservableCollection<Product>(pp);
MainWindow.ViewModel.Instance.Items = oc;

2 个答案:

答案 0 :(得分:2)

首先,将List<Product>更改为ObservableCollection<Product>,因为这将有助于在“添加/删除”上立即显示列表的项目。

这是因为ObservableCollection实现了INotifyCollectionChanged接口以通知您绑定到的目标(DataGrid),以更新其UI。

第二,由于集合引用的更改,绑定无法正常工作。

private void AButton_Click(object sender, RoutedEventArgs e)
{
    // You are changing your Items' reference completely here, the XAML binding 
    // in your View is still bound to the old reference, that is why you're seeing nothing.
    //MainWindow.ViewModel.Instance.Items = Search(searchParam);

    var searchResults = Search(searchParam);
    foreach(var searchResult in searchResults)
    {
        MainWindow.ViewModel.Instance.Items.Add(searchResult);
    }
}

请确保在运行“添加”循环时已将List更改为ObservableCollection,否则您将收到异常消息,说明项目收集状态不一致。

答案 1 :(得分:1)

ViewModel类应实现INotifyPropertyChanged接口并在PropertyChanged设置为新集合时引发其Items事件:

public class ViewModel : INotifyPropertyChanged
{
    private List<ssearch> _items;
    public List<ssearch> Items
    {
        get { return _items; }
        set { _items = value; OnPropertyChanged(); }
    }

    private static ViewModel _instance = new ViewModel();
    public static ViewModel Instance { get { return _instance; } }


    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

这是通知视图的必需项,而与项目的类型无关。

如果将Items的类型更改为ObservableCollection<T>,则应在视图模型一次中初始化集合:

public class ViewModel
{
    public ObservableCollection<ssearch> Items { get; } = new ObservableCollection<ssearch>();

    private static ViewModel _instance = new ViewModel();
    public static ViewModel Instance { get { return _instance; } }
}

...,然后将项目添加到此集合中,而不是将属性设置为新属性:

private void AButton_Click(object sender, RoutedEventArgs e)
{
    MainWindow.ViewModel.Instance.Items.Clear();
    var search = Search(searchParam);
    if (search != null)
        foreach (var x in search)
            MainWindow.ViewModel.Instance.Items.Add(x);

}