WPF 中的 DataGrid 和 Observable 集合 [英] DataGrid and Observable Collection in WPF
问题描述
我的 WPF 应用程序中有一个如下所示的数据网格.
I have a datagrid like below in my WPF application.
<Window x:Class="MyApp.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<DataGrid x:Name="dgTest" ItemsSource="{Binding TestSource}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTemplateColumn Width="125" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Column1}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="500" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Column2}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Click="SaveButton_Click">Save</Button>
</Grid>
</Window>
我使用以下代码绑定它.现在我的要求是当用户在数据网格内的这些文本框中输入一些文本并单击保存按钮时,它应该更新数据库.我怎样才能做到这一点?
I am binding it using the following code. Now my requirement is when the user enters some text into these textboxes inside datagrid and click on save button, it should update the database. How can I achieve this?
namespace MyApp
{
public partial class TestWindow: Window
{
private ObservableCollection<Test> _testSource
public ObservableCollection<Test> TestSource
{
get
{
return _testSource;
}
set
{
_testSource = value;
OnPropertyChanged("TestSource");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
public TestWindow()
{
InitializeComponent();
TestSource= new ObservableCollection<Test>();
string strConnString = Application.Current.Properties["connectionStr"].ToString();
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand("SELECT Column1,Column2 FROM MyTable", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dtTest = new DataTable();
da.Fill(dtTest);
foreach (DataRow row in dtTest)
{
Test cd = new Test();
cd.Column1 = row["Column1"].ToString();
cd.Column2 = row["Column2"].ToString();
TestSource.Add(cd);
}
this.DataContext = this;
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
// here I need to get the updated ObservableCollection, but now it is showing old data
foreach Test t in TestSource)
{
string a = t.Column1;
string b = t.Column2;
}
}
}
public class Test:
{
public string Column1{ get; set; }
public string Column2{ get; set; }
}
}
谢谢
推荐答案
在 DataGridTemplateColumn
(或 自定义 DataGrid.RowStyle
就此而言),DataGrid 更改UpdateSourceTrigger
(即何时应该更新基础数据)在所有绑定到 Explicit
上,如果您没有自己指定它们.
When creating your own UI in DataGridTemplateColumn
(or a custom DataGrid.RowStyle
for that matter), the DataGrid changes the UpdateSourceTrigger
(i.e. when the underlying data should be updated) on all your bindings to Explicit
if you didn't specify them yourself.
此处简要描述了该功能":WPF DataGrid 的 5 个随机问题,即使作者说无论您是否自己设置 UpdateSourceTrigger
都会发生这种情况,设置它你自己确实有效(至少在 .Net 4.0 中).
That "feature" is described briefly here: 5 Random Gotchas with the WPF DataGrid, and even though the author says this happens whether or not you set the UpdateSourceTrigger
yourself, setting it yourself does actually work (at least in .Net 4.0).
使用 LostFocus
来模仿默认的 TextBox
行为(以及 CheckBox
上的 PropertyChanged
等):
Use LostFocus
to mimic the default TextBox
behavior (and PropertyChanged
on CheckBox
etc):
...
<TextBox Text="{Binding Column1, UpdateSourceTrigger=LostFocus}"></TextBox>
...
<TextBox Text="{Binding Column2, UpdateSourceTrigger=LostFocus}"></TextBox>
...
这篇关于WPF 中的 DataGrid 和 Observable 集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!