C# 在 WPF 和 MVVM 中将数据表与 DataGrid 绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9284026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 06:42:43  来源:igfitidea点击:

Bind Datatable with DataGrid in WPF & MVVM

c#wpfmvvm

提问by user178854

I am new to WPF, I am using MVVM pattern in WPF and generating a Datatable structure at the runtime, then binding Datatable with DataGrid/RadGridView, which is working as expected.

我是 WPF 的新手,我在 WPF 中使用 MVVM 模式并在运行时生成一个 Datatable 结构,然后将 Datatable 与 DataGrid/RadGridView 绑定,它按预期工作。

Problem: I want DataGrid/RadGridView configurable (where user can add new row, delete row and edit the data) and on save button click everything should be saved in the database. I have a situation where I need to create an empty DataTable with different columns (depending on user input). And then enter values under those columns and then on click on save need to save value in the database. I am able to bind DataTable to DataGrid (I can see all the column names and data rows if there is already some data in the DataTable in the grid) but NOT able to add (enter) or delete any row at the run time from DataGrid. I have set "True" value for CanUserDeleteRows and CanUserInsertRows. I am not sure where I am going wrong. I am implement INotifyPropertyChanged in my ViewModel class.

问题:我希望 DataGrid/RadGridView 可配置(用户可以在其中添加新行、删除行和编辑数据)并在保存按钮上单击所有内容都应保存在数据库中。我有一种情况,我需要使用不同的列(取决于用户输入)创建一个空的 DataTable。然后在这些列下输入值,然后单击保存需要将值保存在数据库中。我能够将 DataTable 绑定到 DataGrid(如果网格中的 DataTable 中已经有一些数据,我可以看到所有列名和数据行)但无法在运行时从 DataGrid 添加(输入)或删除任何行. 我为 CanUserDeleteRows 和 CanUserInsertRows 设置了“True”值。我不确定我哪里出错了。我在我的 ViewModel 类中实现了 INotifyPropertyChanged。

I am struggling to get the desired result.

我正在努力获得想要的结果。

My code looks like as below:

我的代码如下所示:

ViewModel--

视图模型--

    DataTable _manualDataTable;
    public DataTable ManualDataTable
    {
        get
        {
            return _manualDataTable;
        }
        set
        {
            _manualDataTable = value;
            OnPropertyChanged("ManualDataTable");
        }
    }

For creating DataTable--

用于创建数据表--

    void LoadManualDataTable()
    {
        DataTable dtData = new DataTable();
        dtData.Columns.Add("TimeStamp", typeof(DateTime));
        List<DataColumn> columns = new List<DataColumn>();
        var query = _dataContext.GetSenData().Where(sen => sen.LogID == ((DataLogs)SelectedItemNode).Logger.LogID).Select(sen => sen.SeriesID);
        var queryTS = _dataContext.GetDataSeries().Where(ts => query.Contains(ts.SeriesID));
        foreach (DataSeries ts in queryTS)
        {
            var queryPLoc = _dataContext.GetDataLoc().Where(pLoc => pLoc.ParamID == ts.ParamID).Select(pLoc => pLoc.Name);
            dtData.Columns.Add(queryPLoc.First(), typeof(string));
        }

        ManualDataTable = dtData;
     }

XAML code--

XAML 代码--

     <DataGrid Grid.Row="0" AutoGenerateColumns="True" ItemsSource="{Binding ManualDataTable}" CanUserAddRows="True" CanUserDeleteRows="True" IsReadOnly="False"  Name="dataGridManualData"/>

DataTable is created as expected (from LoadManualDataTable method) and if I will add any row through the code then those rows will be binded and will be displayed in DataGrid. But I am not able to create or delete rows through DataGrid.

DataTable 是按预期创建的(来自 LoadManualDataTable 方法),如果我将通过代码添加任何行,那么这些行将被绑定并显示在 DataGrid 中。但我无法通过 DataGrid 创建或删除行。

Any help will be highly appreciated.

任何帮助将不胜感激。

Thanks in advance!

提前致谢!

回答by blindmeis

i create a simpletestproject to get what you get, but its works without any problem. maybe you should post your code and state what does not work.

我创建了一个简单的测试项目来获得你所得到的,但它的工作没有任何问题。也许你应该发布你的代码并说明什么不起作用。

public partial class MainWindow : Window
{
    public DataTable MyTable { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        this.MyTable= new DataTable();
        this.MyTable.Columns.Add("Test");
        var row1 = this.MyTable.NewRow();
        row1["Test"] = "dsjfks";

        this.MyTable.Rows.Add(row1);

        this.DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("rows: " + this.MyTable.Rows.Count);
    }

}

xaml

xml

<DockPanel>
    <Button Height="23" Content="sdf" Click="Button_Click" />
    <DataGrid ItemsSource="{Binding MyTable}" CanUserAddRows="True"/>
</DockPanel>

回答by guilhermecgs

I am not sure of my answer, but I am going to try...

我不确定我的答案,但我会尝试......

I had the same problem of you: CanUserAddRows always false.

我和你有同样的问题:CanUserAddRows 总是假的。

It turns out that the binding was ok, but the class which I was bindig did not have a default constructor.

结果证明绑定没问题,但是我绑定的类没有默认构造函数。

this Works:

这个作品:

private ObservableCollection<Point> m_points;
public ObservableCollection<Point> Points
{
    get { return m_points; }
    set { m_points = value; }
}

public class Point
{
    public double X { get; set; }
    public double Y { get; set; }

    public Point()
    {
        this.X = 0;
        this.Y = 0;
    }

    public Point(double x, double y)
    {
        this.X = x;
        this.Y = y;
    }
}

this dont work:

这不起作用:

private ObservableCollection<Point> m_points;
public ObservableCollection<Point> Points
{
    get { return m_points; }
    set { m_points = value; }
}

public class Point
{
    public double X { get; set; }
    public double Y { get; set; }

    public Point(double x, double y)
    {
        this.X = x;
        this.Y = y;
    }
}