C# 无法将ObservableCollection绑定到DataGrid

C# 无法将ObservableCollection绑定到DataGrid,c#,wpf,xaml,datagrid,itemssource,C#,Wpf,Xaml,Datagrid,Itemssource,如果我用C#编码就可以了 比如 db在哪里 public ObservableCollection<Data> db = new ObservableCollection<Data>(); db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 }); db.Add(new Data { Name = "person2", Description = "okokok", Price

如果我用C#编码就可以了 比如

db在哪里

public ObservableCollection<Data> db = new ObservableCollection<Data>();

db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 });
db.Add(new Data { Name = "person2", Description = "okokok", Price = 12 });
公共ObservableCollection db=新ObservableCollection(); 添加(新数据{Name=“person1”,Description=“sss”,Price=15}); 添加(新数据{Name=“person2”,Description=“okok”,Price=12}); 它将生成列和数据。。 但是如果我用XAML写,它就不能显示任何东西

<DataGrid ItemsSource="{Binding db}" AutoGenerateColumns="True"/>

我找不到将此集合绑定到DataGrid的方法。。 请告诉我为什么

这是我所有的xaml

<Window x:Class="testt.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel Orientation="Vertical" Name="Panel">
        <TextBlock Name="count"/>
        <DataGrid ItemsSource="{Binding db}" AutoGenerateColumns="True"/>       
    </StackPanel>
</Grid>
</Window>


谢谢

好的,我想你错过了最重要的部分。如果要使用
绑定
,必须在视图的某个位置设置
数据上下文
。这是
绑定理论的良好开端

通常,您会使用
ViewModel
进行此操作。例如

public class WndViewModel : ViewModelBase // the base class implementing INotifyPropertyChanged
                                          // although you don't need it for your case 
{
    private ObservableCollection<Data> _db;
    public ObservableCollection<Data> Db 
    { 
        get { return _db ?? (_db = new ObservableCollection<Data>()); 
    }

    public WndViewModel()
    {
        Db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 });
        Db.Add(new Data { Name = "person2", Description = "okokok", Price = 12 });
    }
}
请注意,此代码仅用于演示目的,需要改进以获得良好的解决方案


我还建议您熟悉
MVVM
模式。您可以从阅读文章开始。

如果您不使用MVVM,请在代码中尝试此功能

DataGrid dg = new DataGrid();
dg.AutoGenerateColumns = true;
dg.ItemsSource = db;
this.DataContext = this; //or put this line in constructor.
db在哪里

public ObservableCollection<Data> db = new ObservableCollection<Data>();

db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 });
db.Add(new Data { Name = "person2", Description = "okokok", Price = 12 });
公共ObservableCollection db=新ObservableCollection(); 添加(新数据{Name=“person1”,Description=“sss”,Price=15}); 添加(新数据{Name=“person2”,Description=“okok”,Price=12});
在Xaml中

<Window x:Class="testt.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel Orientation="Vertical" Name="Panel">
        <TextBlock Name="count"/>
        <DataGrid ItemsSource="{Binding db}" AutoGenerateColumns="True"/>       
    </StackPanel>
</Grid>
</Window>

您必须设置窗口的datacontext,才能将集合与其下的控件绑定在一起

ObservableCollection<Data> db = new ObservableCollection<Data>();

 db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 });
 db.Add(new Data { Name = "person2", Description = "okokok", Price = 12 });

 this.DataContext = db;
ObservableCollection db=新的ObservableCollection();
添加(新数据{Name=“person1”,Description=“sss”,Price=15});
添加(新数据{Name=“person2”,Description=“okok”,Price=12});
this.DataContext=db;
现在在XAML中,您只设置itemsource的绑定

<DataGrid Name="grdPerson" ItemsSource="{Binding}" AutoGenerateColumns="True"></DataGrid>

尝试为DataGrid设置“DisplayMemberPath”,这是设置数据源后应该做的第一件事。

您必须实现
INotifyPropertyChanged
接口以反映更改。请参阅下面的代码片段

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace StylingIntroSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window,INotifyPropertyChanged
{
    private ObservableCollection<Data> _db = new ObservableCollection<Data>();

    public ObservableCollection<Data> db {
        get { return _db; }
        set
        {
            _db = value;
            OnPropertyChanged("db");
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        LoadItems();
    }

    private void LoadItems()
    {
        db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 });
        db.Add(new Data { Name = "person2", Description = "okokok", Price = 12 });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string PropertyName)
    {
        if (PropertyChanged!= null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
}

public class Data
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int Price { get; set; }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
使用System.Collections.ObjectModel;
使用系统组件模型;
命名空间样式Introsample
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口,INotifyPropertyChanged
{
私有ObservableCollection_db=新ObservableCollection();
公共可观测收集数据库{
获取{return\u db;}
设置
{
_db=数值;
不动产变更(“db”);
}
}
公共主窗口()
{
初始化组件();
this.DataContext=this;
LoadItems();
}
私有void LoadItems()
{
添加(新数据{Name=“person1”,Description=“sss”,Price=15});
添加(新数据{Name=“person2”,Description=“okok”,Price=12});
}
公共事件属性更改事件处理程序属性更改;
公共void OnPropertyChanged(字符串PropertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(PropertyName));
}
}
}
公共类数据
{
公共字符串名称{get;set;}
公共字符串说明{get;set;}
公共整数价格{get;set;}
}
}

在XAML中
谢谢您的帮助 现在问题解决了

db应该是属性,而不是字段,所以我将一些代码更改为

public ObservableCollection<Data> db { set; get; }

现在它可以正常工作了:)

您是否设置了
窗口的
DataContext
或任何其他子项?我必须将哪些项设置为DataContext?db是否正在调用,调试它..db必须是公共属性,在您的情况下,它是一个字段。@SuperMENG已经提供了ItemsSource和AutoGeneratedColumns=True@VimalCK:我认为“DisplayMemberPath”是一个属性,它告诉DataGrid显示它绑定到的集合的属性。仅设置ItemSource不会通过默认值添加该属性您是否尝试使用DisplayMemberPath,它是否对您有效?不,我无法检查它,但我经历过这种情况,在这些情况下,我错过了使用DisplayMemberPath,它在我添加它时起作用。我尝试过,但它不起作用。这里的问题是视图没有得到datacontext属性的通知。因此INotifyPropertyChanged事件将引发并关闭UI层以更新新值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace StylingIntroSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window,INotifyPropertyChanged
{
    private ObservableCollection<Data> _db = new ObservableCollection<Data>();

    public ObservableCollection<Data> db {
        get { return _db; }
        set
        {
            _db = value;
            OnPropertyChanged("db");
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        LoadItems();
    }

    private void LoadItems()
    {
        db.Add(new Data { Name = "person1", Description = "sssssss", Price = 15 });
        db.Add(new Data { Name = "person2", Description = "okokok", Price = 12 });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string PropertyName)
    {
        if (PropertyChanged!= null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
}

public class Data
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int Price { get; set; }
}
<Grid>
    <StackPanel Orientation="Vertical"
                Name="Panel">
        <TextBlock Name="count" />
        <DataGrid Name="MyGrid" ItemsSource="{Binding db}"
                  AutoGenerateColumns="True" />
    </StackPanel>
</Grid>
public ObservableCollection<Data> db { set; get; }
this.DataContext = this;