C# 如何在WPF数据网格中将单元格集中在新行上
.Net 4 WPF数据网格MVVM 用户单击“添加”按钮,该按钮将触发viewmodel上的命令。在viewmodel命令execute中,我向网格绑定到的viewmodel的viewcollection添加了一个新对象。新行确实出现在我的网格中。但是,我还想将焦点发送到新行中的第一个可编辑单元格 我甚至“欺骗”了mvvm,在我的viewmodel上添加了一个视图监听的事件,以知道何时聚焦新行 我已经找过了,但运气不好。当我遇到这个问题时,我满怀希望: 这导致了 但其他人已经报道但没有人回答的问题是如何处理网格的虚拟化行为。尚未创建新添加的行。因此GetCells调用经常失败。如果需要ScrollIntoView,那么失败的可能性就大得多C# 如何在WPF数据网格中将单元格集中在新行上,c#,.net,wpf,datagrid,C#,.net,Wpf,Datagrid,.Net 4 WPF数据网格MVVM 用户单击“添加”按钮,该按钮将触发viewmodel上的命令。在viewmodel命令execute中,我向网格绑定到的viewmodel的viewcollection添加了一个新对象。新行确实出现在我的网格中。但是,我还想将焦点发送到新行中的第一个可编辑单元格 我甚至“欺骗”了mvvm,在我的viewmodel上添加了一个视图监听的事件,以知道何时聚焦新行 我已经找过了,但运气不好。当我遇到这个问题时,我满怀希望: 这导致了 但其他人已经报道但没有人回
我已经钓到了很多事件,包括LoadingRow和RequestBringIntoView,但运气不好。根据我钩住的事件,我已经设法获得了对单元格的引用。但是我得到一个错误“当内容生成正在进行时无法调用StartAt”。但是我检查了ItemContainerGenerator的状态,当我调用单元格的BeginEdit时,它是ContainerGenerator。以下是一种通过编程方式将焦点设置到特定单元格的方法:
DataGridCell cell = GetCell(rowIndex, colIndex);
cell.Focus;
有关GetCell()的更多信息,请参见以下内容。这似乎对我很有用:
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
private void SetFocusOnNewRow(DataGrid theDataGrid, Int32 columnIndex)
{
theDataGrid.UnselectAll();
theDataGrid.UpdateLayout();
Int32 newRowIndex = theDataGrid.Items.Count - 1;
theDataGrid.ScrollIntoView(theDataGrid.Items[newRowIndex]);
DataGridRow newDataGridRow = theDataGrid.ItemContainerGenerator.ContainerFromIndex(newRowIndex) as DataGridRow;
DataGridCellsPresenter newDataGridCellsPresenter = GetVisualChild<DataGridCellsPresenter>(newDataGridRow);
if (newDataGridCellsPresenter != null)
{
DataGridCell newDataGridCell = newDataGridCellsPresenter.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell;
if (newDataGridCell != null)
newDataGridCell.Focus();
}
}
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;
}
private void button_Click(object sender, RoutedEventArgs e)
{
//Scroll to the last row
var border = VisualTreeHelper.GetChild(dataGrid, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null) scroll.ScrollToEnd();
}
//Edit the first cell of the last row
int lastRow = dataGrid.Items.Count - 1;
DataGridCell cell = GetCell(lastRow, 0);
cell.Focus();
dataGrid.BeginEdit();
}
public DataGridCell GetCell(int row, int column)
{
DataGridRow rowContainer = GetRow(row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
// try to get the cell but it may possibly be virtualized
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
if (cell == null)
{
// now try to bring into view and retreive the cell
dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
}
return cell;
}
return null;
}
public DataGridRow GetRow(int index)
{
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// may be virtualized, bring into view and try again
dataGrid.ScrollIntoView(dataGrid.Items[index]);
row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
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;
}
使用System.Windows.Controls;
使用System.Windows.Controls.Primitives;
使用System.Windows.Media;
私有void setFocusonnerRow(数据网格和数据网格,Int32列索引)
{
DataGrid.UnselectAll();
datagrid.UpdateLayout();
Int32 newRowIndex=theDataGrid.Items.Count-1;
滚动到视图(datagrid.Items[newRowIndex]);
DataGridRow newDataGridRow=DataGrid.ItemContainerGenerator.ContainerFromIndex(newRowIndex)作为DataGridRow;
DataGridCellsPresenter newDataGridCellsPresenter=GetVisualChild(newDataGridRow);
if(newDataGridCellsPresenter!=null)
{
DataGridCell newDataGridCell=newDataGridCellsPresenter.ItemContainerGenerator.ContainerFromIndex(columnIndex)作为DataGridCell;
if(newDataGridCell!=null)
newDataGridCell.Focus();
}
}
静态T GetVisualChild(可视父级),其中T:Visual
{
T child=默认值(T);
int numVisuals=VisualTreeHelper.GetChildrenCount(父级);
对于(int i=0;i
这是我的工作:
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
private void SetFocusOnNewRow(DataGrid theDataGrid, Int32 columnIndex)
{
theDataGrid.UnselectAll();
theDataGrid.UpdateLayout();
Int32 newRowIndex = theDataGrid.Items.Count - 1;
theDataGrid.ScrollIntoView(theDataGrid.Items[newRowIndex]);
DataGridRow newDataGridRow = theDataGrid.ItemContainerGenerator.ContainerFromIndex(newRowIndex) as DataGridRow;
DataGridCellsPresenter newDataGridCellsPresenter = GetVisualChild<DataGridCellsPresenter>(newDataGridRow);
if (newDataGridCellsPresenter != null)
{
DataGridCell newDataGridCell = newDataGridCellsPresenter.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell;
if (newDataGridCell != null)
newDataGridCell.Focus();
}
}
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;
}
private void button_Click(object sender, RoutedEventArgs e)
{
//Scroll to the last row
var border = VisualTreeHelper.GetChild(dataGrid, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null) scroll.ScrollToEnd();
}
//Edit the first cell of the last row
int lastRow = dataGrid.Items.Count - 1;
DataGridCell cell = GetCell(lastRow, 0);
cell.Focus();
dataGrid.BeginEdit();
}
public DataGridCell GetCell(int row, int column)
{
DataGridRow rowContainer = GetRow(row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
// try to get the cell but it may possibly be virtualized
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
if (cell == null)
{
// now try to bring into view and retreive the cell
dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
}
return cell;
}
return null;
}
public DataGridRow GetRow(int index)
{
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// may be virtualized, bring into view and try again
dataGrid.ScrollIntoView(dataGrid.Items[index]);
row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
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;
}
private void按钮\u单击(对象发送者,路由目标)
{
//滚动到最后一行
var border=VisualTreeHelper.GetChild(dataGrid,0)作为装饰器;
如果(边框!=null)
{
var scroll=border.Child作为ScrollViewer;
如果(scroll!=null)scroll.ScrollToEnd();
}
//编辑最后一行的第一个单元格
int lastRow=dataGrid.Items.Count-1;
DataGridCell=GetCell(lastRow,0);
cell.Focus();
dataGrid.BeginEdit();
}
公共DataGridCell GetCell(int行,int列)
{
DataGridRow rowContainer=GetRow(行);
if(rowContainer!=null)
{
DataGridCellsPresenter=GetVisualChild(行容器);
//尝试获取该单元,但它可能已虚拟化
DataGridCell=(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(列);
if(单元格==null)
{
//现在试着把手机放在视野里,然后拿回手机
ScrollIntoView(rowContainer,dataGrid.Columns[column]);
单元格=(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(列);
}
返回单元;
}
返回null;
}
公共DataGridRow GetRow(int索引)
{
DataGridRow=(DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(索引);
if(行==null)
{
//可能已虚拟化,请查看并重试
ScrollIntoView(dataGrid.Items[index]);
行=(DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(索引);
}
返回行;
}
静态T GetVisualChild(可视父级),其中T:Visual
{
T child=默认值(T);
int numVisuals=VisualTreeHelper.GetChildrenCount(父级);
对于(int i=0;i
???你读过我的问题吗???我已经包含了一个指向该页面的链接,而GetCell的问题是,如果尚未创建单元格,它将不起作用。请在ScrollIntoView之前尝试调用dg.UpdateLayout(),这样可以工作!!!!早些时候,我发现了一个修复方法,我必须“分派”一个函数调用,优先级正常,这是可行的。但到目前为止,在ScrollIntoView之前调用UpdateLayout似乎是可靠的。谢谢欢迎您-很抱歉最初误读了您的问题虽然此代码可以回答问题,但最好在不介绍其他人的情况下解释它如何解决问题以及为什么使用它。从长远来看,纯代码的答案是没有用的。很抱歉,我对这一点非常陌生,因为我认为代码是使用所选变量名进行自我记录的。