2014-02-27 41 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

相關問題