[英]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: 您可以做的其他一些事情是:
[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)
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及更高版本) 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: 由于您将
DataGrid
的DataContext
设置为DataTable
的DataView
,如下所示:
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.