【问题标题】:Binding DataTable to DataGrid C# WPF MVVM将 DataTable 绑定到 DataGrid C# WPF MVVM
【发布时间】:2023-04-02 14:08:01
【问题描述】:

MVVM 新手,在尝试将动态生成的 DataTable 与 DataGrid 绑定时,我一直在努力找出问题所在。我找到了一些解决方案,并尝试根据之前的回复对我的实现进行调整:

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:

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

视图模型

.演讲者:

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

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

我知道模型中的数据正确返回,当我在调试器中时,RaisePropertyChangedEvent 正在触发,但视图没有被更新。

【问题讨论】:

  • 重要提示:如果您使用 C#6 或更高版本,则可以使用 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 而不是创建变量并检查 null :)
  • 首先将数据表重命名为数据表,这个问题只是烦人。第二个属性名称使用“DataTable”而不是“Grid”或使用适当的通知实现。也可以在c#6中使用nameof(DataGrid)
  • 实施了这两个建议;仍然没有让它发挥作用,但是我在这里所做的更改,我希望以前的文章可以让我振作起来。

标签: c# wpf mvvm data-binding wpfdatagrid


【解决方案1】:

您提出了错误的 PropertyName(这似乎是您在 XAML 中的 Grid 的名称。

在调用您的 RaisePropertyChanged 方法时提升名称 "dataTable"

像这样:

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

您可以做的其他一些事情是:

  • propertyName 参数之前使用[CallerMemberName] 属性。这将使您不必提供它,因为它会检测到调用它的属性(C#5 及更高版本) - 例如:protected void RaisePropertyChangedEvent([CallerMemberName] string propertyName)
  • 在您的RaisePropertyChanged 方法中使用PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));。这样您就不必创建变量并检查 null(C#6 及更高版本)
  • 将您的 dataTable 属性重命名为 DataTable - 它可以更清楚地说明什么是属性和什么是字段,这在 C# 中很常见

希望这会有所帮助:)

【讨论】:

  • 感谢您的回复。我将名称更改为“dataTable”,但仍然无法正常工作。我还将根据您的反馈进行重构。我担心我在 XAML 标头中的绑定不正确,这可能是它没有提取正确信息的原因吗?
【解决方案2】:

由于您将DataGridDataContext 设置为DataTableDataView,如下所示:

Grid.DataContext = dataTable.DefaultView;

...你应该直接绑定到DataContext:

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

如果您想绑定到您的 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">

然后可以将Presenter对象的dataTable属性设置为新的DataTable

p.dataTable = new DataTable();

您仍然需要按照@Geoff James 的建议修改您的属性:

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

【讨论】:

    猜你喜欢
    • 2018-02-07
    • 1970-01-01
    • 2013-03-24
    • 2013-07-28
    • 2012-03-06
    • 1970-01-01
    • 2019-12-22
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多