我会尽可能清楚地说明这一点,但我很清楚我可能会问错误的问题。我在WPF(.NET 4.0)中有一个datagrd,它绑定到数据集中的数据表。相关的代码隐藏(在窗口加载上运行)是:
// create a connection to Top Trumps database
String cs = ConfigurationManager.ConnectionStrings["csTopTrumps"].ConnectionString;
SqlConnection cn = new SqlConnection(cs);
// create a new dataset
DataSet ds = new DataSet();
// open the connection (not strictly necessary, as the
// data adapter will do this when you use it anyway)
cn.Open();
// fill data table called Cards with contents of tblCard
SqlDataAdapter daCards = new SqlDataAdapter();
daCards.SelectCommand =
new SqlCommand("SELECT * FROM tblCard ORDER BY CardTitle", cn);
daCards.Fill(ds, "Cards");
// now set the data context for the entire window
this.DataContext = ds;
我的数据网格定义开始:
<DataGrid ItemsSource="{Binding Tables[Cards]}"
所有这些都很好,我明白了。我现在想要以两种方式进行数据绑定,以便在datagrid中进行的更改将更新回底层数据库。我知道我可以做到这一点的一种方法是获取已更改行的值,并使用带有Update方法的tableadapter将任何更改写回底层数据库(可能是像SelectedCellsChanged事件或类似事件)。但是,任何这样的方法都难以实现,因为在WPF中代码隐藏中获取单元格值很困难(我的理解是这是错误的方法,因为我应该使用WPF框架,所以帮助我)。
那么......我怎样才能设置双向数据绑定来为我做这项工作?我见过人们提到设置datagrid属性,如:
SelectedItem="{Binding Path=SelectedIndex,Mode=TwoWay}"
但我不明白如何使用数据适配器和数据集。我不想要的是涉及MVVM或模型的任何解决方案,因为我没有使用这些(是的,我可能应该是,我知道)。我还想避免大量复杂的C#代码,涉及可观察的集合,通过控制层次结构的递归搜索来查找父母等等。
我已经搜索了很长时间,我想我所问的确实存在 - 如果没有,请告诉我它没有,并为浪费你的时间而道歉,温柔的读者!
答案 0 :(得分:0)
我完全不理解你。您希望避免使用WPF框架(可观察的集合,绑定,递归搜索等),但是您希望找到使用WPF框架的方法。
首先你需要这些功能:
public static T GetVisualChild<T>(Visual parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
public static DataGridRow GetSelectedRow(this DataGrid grid)
{
return (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem);
}
public static DataGridRow GetRow(this DataGrid grid, int index)
{
DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// May be virtualized, bring into view and try again.
grid.UpdateLayout();
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
{
if (row != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
if (presenter == null)
{
grid.ScrollIntoView(row, grid.Columns[column]);
presenter = GetVisualChild<DataGridCellsPresenter>(row);
}
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
return cell;
}
return null;
}
public static DataGridCell GetCell(this DataGrid grid, int row, int column)
{
DataGridRow rowContainer = grid.GetRow(row);
return grid.GetCell(rowContainer, column);
}
现在DataGrid实际上有几乎有用的事件。它被称为CellEditEnding。 把它挂起来
private bool isManualEditCommit;
private void yourHandler(
object sender, DataGridCellEditEndingEventArgs e)
{
if (!isManualEditCommit)
{
isManualEditCommit = true;
DataGrid grid = (DataGrid)sender;
grid.CommitEdit(DataGridEditingUnit.Row, true);
isManualEditCommit = false;
} else {
/* you can write foreach loop that would loop through all the DataGridCells
with DataGridCell cell = grid.GetCell(row, col),
you can recieve value like GetVisualChild<TextBlock>(cell).Text
and update everything when you're at last value */
}
}
也读过这个; WPF DataGrid CellEditEnding - DataSet Not Updating Till Row Lost Focus
这很难,但如果您有经验,可以提供更好的代码。 尝试搜索术语数据绑定,datagrid,datagridtemplatecolumn,双向绑定,cellEditEnding。
祝你好运!答案 1 :(得分:0)
好的,有点晚了,我想我得到了我想要的答案。 datagrid绑定到数据表(在我的实例中)。这意味着您可以获取所选项目(可能是用户双击的行),将其转换为数据行,然后到达您感兴趣的字段。
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// turn the datagrid selected "item" into a data row
DataRowView dr = dg.SelectedItem as DataRowView;
// get at the value for any field (here it's the one called CARD) in the underlying datatable
string CardTitle = (string)dr["Card"];
// display it ...
MessageBox.Show("You are on card " + CardTitle);
}
这将解决双击数据网格中的行的问题,这也是我的想法。如果您正在使用类,则可以将所选项目转换为相关对象,并获取其属性。
我希望这有助于某人!