C# 在数据网格中存储和更改值——MVVM
在我的程序中,我有一个C# 在数据网格中存储和更改值——MVVM,c#,wpf,mvvm,datagrid,C#,Wpf,Mvvm,Datagrid,在我的程序中,我有一个DataGrid,它是UserControl的一部分。我希望能够更改网格中单元格的值,并将它们存储在数据模型中。这类似于标准数据绑定textBox在wpf中的工作方式 DataGrid由TextBoxes组成。我可以更改单元格中的值,但它们在离开页面后消失 UserControl XAML: <DataGrid ItemsSource="{Binding DataModel.Collection}" ... > <DataGri
DataGrid
,它是UserControl的一部分。我希望能够更改网格中单元格的值,并将它们存储在数据模型中。这类似于标准数据绑定textBox
在wpf中的工作方式
DataGrid
由TextBox
es组成。我可以更改单元格中的值,但它们在离开页面后消失
UserControl XAML:
<DataGrid ItemsSource="{Binding DataModel.Collection}" ... >
<DataGrid.Columns>
<DataGridTemplateColumn IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding rowNum}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
.......
</DataGrid>
.......
数据模型:
public class Data_Model : PropertyChangedBase
{
private string one = "One";
private string two = "Two";
private string three = "Three";
private string four = "Four";
private string a = "A";
private string b = "B";
private string c = "C";
private string d = "D";
private ObservableCollection<Class> _Collection;
public Data_Model()
{
Collection = new ObservableCollection<Class>();
Collection.Add(new Class() { rowNum = 0, input = one, output = a });
Collection.Add(new Class() { rowNum = 1, input = two, output = b});
Collection.Add(new Class() { rowNum = 2, input = three, output = c});
Collection.Add(new Class() { rowNum = 3, input = four, output = d});
}
public ObservableCollection<Class> Collection {...}
}
public class Class //Class for DataGrid values
{
public int rowNum { set; get; }
public string input { set; get; }
public string output { set; get; }
}
公共类数据\u模型:PropertyChangedBase
{
私有字符串one=“one”;
私有字符串two=“two”;
私有字符串三=“三”;
私有字符串四=“四”;
私有字符串a=“a”;
私有字符串b=“b”;
私有字符串c=“c”;
私有字符串d=“d”;
私人可观测采集(u采集);;
公共数据_模型()
{
集合=新的ObservableCollection();
Add(新类(){rowNum=0,输入=1,输出=a});
Add(新类(){rowNum=1,输入=2,输出=b});
Add(新类(){rowNum=2,输入=3,输出=c});
Add(新类(){rowNum=3,输入=4,输出=d});
}
公共ObservableCollection集合{…}
}
数据网格值的公共类//类
{
public int rowNum{set;get;}
公共字符串输入{set;get;}
公共字符串输出{set;get;}
}
如何将用户输入的值像通常那样存储在这些单元格中(通过为用作
文本框
中文本的字符串
编写属性)?当单元格可编辑时,WPF DataGrid使用事务范围。这意味着DataGrid正在发布“提交”和“取消”命令,而您的视图模型目前没有监听这些命令。这就是为什么更改看起来不会持久(即,您忽略了这些实例上的“提交”)
为了捕获“提交”和“取消”消息,绑定类应该实现IEditableObject并编写必要的逻辑代码。IEditableObject上的文档如下:
当对行执行“取消”时,网格将回滚对该行的单元格执行的所有提交。WPF数据网格的这一方面已经迷惑了很多人,因此它获得了“抓住”的地位
如果您不熟悉IEditableObject,请参阅这篇MSDN文章
它有很好的解释和代码示例。数据网格已经成熟
在通过IEditableObject进行事务性编辑的功能中
接口。当您开始编辑单元格时,DataGrid进入单元格
编辑模式以及行编辑模式。这意味着你
可以取消/提交单元格以及取消/提交行。例如,我
编辑单元格0并按tab键进入下一个单元格。单元格0在
按tab键。我开始在单元格1中输入,意识到我想取消
手术。我按下“Esc”键,它将恢复单元格1。我现在意识到我
想取消整个操作,所以我再次按下“Esc”,现在按下单元格
0将恢复为其原始值
资料来源:
因此,在“Class”类上实现IEditableObject,您将开始获得所需的行为。这就是你完成后的样子
public class Class : INotifyPropertyChanged, IEditableObject
{
private int _rowNum;
public int RowNum
{
[DebuggerStepThrough]
get { return _rowNum; }
[DebuggerStepThrough]
set
{
if (value != _rowNum)
{
_rowNum = value;
OnPropertyChanged("RowNum");
}
}
}
private string _input;
public string Input
{
[DebuggerStepThrough]
get { return _input; }
[DebuggerStepThrough]
set
{
if (value != _input)
{
_input = value;
OnPropertyChanged("Input");
}
}
}
private string _output;
public string Output
{
[DebuggerStepThrough]
get { return _output; }
[DebuggerStepThrough]
set
{
if (value != _output)
{
_output = value;
OnPropertyChanged("Output");
}
}
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
#region IEditableObject Implementationi
public void BeginEdit()
{
// your implementation goes here
}
public void CancelEdit()
{
// your implementation goes here
}
public void EndEdit()
{
// your implementation goes here
}
#endregion
}
我相信您只需要为数据模型中的每个属性调用NotifyPropertyChanged(“PropertyName”),并设置绑定
Mode=twoway
private int rowNum;
public int RowNum
{
get { return rowNum; }
set
{
rowNum = value;
RaisePropertyChanged("RowNum");
}
}
另外,您可以尝试DataGridTextColumn而不是templatecolumn,如下所示
<Window.Resources>
<XmlDataProvider x:Key="customerdata" Source="customers.xml" XPath="Data" />
</Window.Resources>
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource customerdata}, XPath=Customer}">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding XPath=@FirstName}" FontFamily="Arial" FontStyle="Italic" />
<DataGridTextColumn Header="Last Name" Binding="{Binding XPath=@LastName}" FontFamily="Arial" FontWeight="Bold" />
</DataGrid.Columns>
</DataGrid>
</Grid>
你的类名把我弄糊涂了。似乎DataClass
是您的模型(或数据模型),而Data\u Model
实际上是您的视图模型……为什么要将列模板化为TextBox
es?如果这是出于编辑目的,DataGrid
支持开箱即用,则固定名称Class
仅用于存储在DataGrid
中的值,而Data\u Model
是我的数据模型。也。。。如果不是TextBox
,那么在没有控件的情况下,我如何准确地执行等效操作?默认情况下,WPF TextBox绑定两种方式。对DataGridTextColumn
的更改对我有效。谢谢!