2014-02-27 45 views
1

我在互联网上看到这个主题很常见,我不明白为什么还没有创建一个方法来直接选择datagridview中的单元。在datagridview中选择一个单元并开始编辑

我创建了这个类助手:

using Microsoft.Windows.Controls.Primitives; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace gestione_magazzino_v4.Classi 
{ 
    static class DataGridViewHelper 
    { 
     static public DataGridCell GetCell(DataGrid dg, int row, int column) 
     { 
      DataGridRow rowContainer = GetRow(dg, row); 

      if (rowContainer != null) 
      { 
       DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer); 

       DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); // <<<------ ERROR 
       if (cell == null) 
       { 
        // now try to bring into view and retreive the cell 
        dg.ScrollIntoView(rowContainer, dg.Columns[column]); 
        cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); 
       } 
       return cell; 
      } 
      return null; 
     } 

     static public DataGridRow GetRow(DataGrid dg, int index) 
     { 
      DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index); 
      if (row == null) 
      { 
       // may be virtualized, bring into view and try again 
       dg.ScrollIntoView(dg.Items[index]); 
       row = (DataGridRow)dg.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; 
     } 
    } 
} 

我用这个代码:

DataGridCell cell = DataGridViewHelper.GetCell(datagridview, 0, 2); 
if (cell != null) 
    cell.Focus(); 

但我得到一个错误,我特别强调了,我得到System.NullReferenceException

我不明白缺少什么...网上有很多例子,但它们都与我所做的相同,不明白什么是失踪!

+0

你能与调试器附加检查该'presenter'为空? –

+0

是...'presenter' si null ...是'GetVisualChild'返回值始终为空... – user2263764

回答

0

Foud解决方案! 的问题是使用:

using Microsoft.Windows.Controls.Primitives; 

但正确的是:

using System.Windows.Controls.Primitives; 
0

DataGridCellPresenter为空,这是由于DataGrid的虚拟化。

假设您有100行,并且向下滚动到行[49],其中该行是屏幕上最可见的行,对于行0-48,它们的DataGridCellPresenter是Virtualized(disposed)。

DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer); 
if(presenter != null) 
{ 
    // Select your cell... 
} 

这是如果你正在滚动,当你尝试这样做时,首先显示您的用户控件(或任何形式的视图)对于这种情况的另一个例子是后选择它。

您必须等待数据网格负载:

dataGrid.Loaded += DG_Loaded; 


void DG_Loaded(object sender, System.Windows.RoutedEventArgs e) 
{ 
     ScrollViewer _sv = GetVisualChild<ScrollViewer>(dataGrid);   
} 

之前DataGrid中加载完所有它的VisualTree尚未建立,包括它的最顶端子上面显示的ScrollViewer中。

这个替换您GetVisualChild:

public static T GetVisualChild<T>(DependencyObject depObj) where T : Visual 
{ 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 

       if (child != null && child is T) 
       { 
        return (T)child; 
       } 

       foreach (T childOfChild in GetVisualChild<T>(child)) 
       { 
        return childOfChild; 
       } 
      } 
     } 
     return null; 
    } 

什么,我认为是错误的,并非所有对你的方式要素下的可视化树是视觉的, 例如沿途任何面板不是Visual ,所以当你将它转换为Visual时,你会得到null,永远不会到达DataGridCellPresenter。

+0

是的....但在我的测试中,datagrid只有两行... – user2263764

+0

你在什么时候尝试获取单元格,是否已经创建了DataGrid,然后将其发送给帮助器? 或者它是在一个构造函数或回调的依赖属性 后,你可以调用DataGridViewHelper.GetCell(datagridview,0,2); –

+0

接口完全充电后,加载完数据后(2行)。 通过单击按钮 'DataGridCell cell = DataGridViewHelper。GetCell(datagridview,0,2);' – user2263764

相关问题