简体   繁体   English

将DataTable绑定到DataGrid C#WPF MVVM

[英]Binding DataTable to DataGrid C# WPF MVVM

New to MVVM and struggling to figure out where I went wrong when attempting to bind a dynamically generated DataTable with a DataGrid. MVVM的新增功能,试图找出将动态生成的DataTable与DataGrid绑定时出了错的地方。 I've found some solutions and attempted to make adjustments to my implementation based on previous responses: 我找到了一些解决方案,并尝试根据以前的响应对我的实现进行调整:

XAML: XAML:

<DataGrid x:Name="Grid" Margin="5,0,0,0" ItemsSource="{Binding dataTable, Mode=TwoWay}" AutoGenerateColumns="False" VerticalAlignment="Center">
<DataGrid.Columns>
    <DataGridTextColumn Header="Header1" Binding="{Binding Column1Name}"/>
    <DataGridTextColumn Header="Header2" Binding="{Binding Column2Name}"/>
</DataGrid.Columns>
<DataGrid.DataContext>
    <ViewModels:Presenter/>
</DataGrid.DataContext>

XAML CS: XAML CS:

DataTable dataTable = new DataTable();
Grid.DataContext = dataTable.DefaultView;
//I don't believe I should be using System.Data in View?

ViewModel 视图模型

.Presenter: 。主持人:

public class Presenter : ObservableObject {
private DataTable _dataTable;


public DataTable dataTable
    {
        get { return _dataTable; }
        set
        {
            _dataTable = value;
            RaisePropertyChangedEvent("Grid");
        }
    }

private void ParseData()
    {
        if (string.IsNullOrWhiteSpace(ID)) return;
        dataTable = DataParser.ParseURL(ID);
    }
}

.ObservableObject .ObservableObject

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

I know the data from the model is returning correctly, and when I'm in debugger the RaisePropertyChangedEvent is firing, but the view is not being updated. 我知道模型中的数据可以正确返回,并且当我在调试器中时,会触发RaisePropertyChangedEvent,但视图未更新。

You're raising the wrong PropertyName (which appears to be the name of your Grid in the XAML. 您提出了错误的PropertyName (它似乎是XAML中Grid的名称)。

Raise the name "dataTable" when calling your RaisePropertyChanged method. 调用RaisePropertyChanged方法时,请提高名称"dataTable"

Like so: 像这样:

public DataTable dataTable
{
    get { return _dataTable; }
    set
    {
        _dataTable = value;
        RaisePropertyChangedEvent("dataTable");
    }
}

A few other things you can do are: 您可以做的其他一些事情是:

  • Use [CallerMemberName] attribute before the propertyName parameter. propertyName参数之前使用[CallerMemberName]属性。 This will save you having to provide it, as it detects what property is calling it (C#5 and above) - eg: protected void RaisePropertyChangedEvent([CallerMemberName] string propertyName) 这将省去您提供它的protected void RaisePropertyChangedEvent([CallerMemberName] string propertyName) ,因为它可以检测到调用它的属性(C#5及更高版本)-例如: protected void RaisePropertyChangedEvent([CallerMemberName] string propertyName)
  • Use PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 使用PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); in your RaisePropertyChanged method. 在您的RaisePropertyChanged方法中。 This saves you having to create a variable and check for null (C#6 and above) 这省去了创建变量并检查是否为null (C#6及更高版本)
  • Rename your dataTable property to DataTable - it creates better clarity as to what are properties and what are fields, and it's a commonplace thing to do in C# 将您的dataTable属性重命名为DataTable可以更清楚地了解什么是属性和什么是字段,这在C#中是很平常的事情

Hope this helps :) 希望这可以帮助 :)

Since you are setting the DataContext of the DataGrid to the DataView of the DataTable like this: 由于您将DataGridDataContext设置为DataTableDataView ,如下所示:

Grid.DataContext = dataTable.DefaultView;

...you should bind directly to the DataContext : ...您应该直接绑定到DataContext

<DataGrid x:Name="Grid" Margin="5,0,0,0" ItemsSource="{Binding}" AutoGenerateColumns="False" VerticalAlignment="Center">
...

If you want to bind to your dataTable property, you should set the DataContext to an instance of your Presenter class: 如果要绑定到dataTable属性,则应将DataContext设置为Presenter类的实例:

var p = new Presenter();
Grid.DataContext = p;

<DataGrid x:Name="Grid" Margin="5,0,0,0" ItemsSource="{Binding dataTable}" AutoGenerateColumns="False" VerticalAlignment="Center">

Then you can set the dataTable property of the Presenter object to a new DataTable : 然后,可以将Presenter对象的dataTable属性设置为新的DataTable

p.dataTable = new DataTable();

You still need to modify your property as suggested by @Geoff James: 您仍然需要按照@Geoff James的建议修改属性:

public DataTable dataTable
{
    get { return _dataTable; }
    set
    {
        _dataTable = value;
        RaisePropertyChangedEvent("dataTable");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM