2010-07-22 45 views
6

我有一個綁定到可觀察集合的數據網格。 當用戶按下「添加按鈕」時,它會添加一個新行,我通過向observablecollection添加一個新元素來完成此操作。Datagrid將重點放在新添加的行上

我無法弄清楚如何使第一個單元格的新添加的行焦點,就好像我們正在編輯。我正在使用MVVM模式。

任何想法或建議嗎?

回答

0

嘗試捕獲DataGrid的LoadingRow(或類似)事件。在行上執行SetFocus(e.Row)(或類似)。這純粹是面向View的,所以它符合MVVM。

0

你想要做這樣的事情:

DataGridCell cell = GetCell(rowIndex, colIndex); 
cell.Focus; 

當然你需要一個難以捉摸GetCell()方法。來自MSFT的Vincent Sibal在this forum post中寫下了該方法(以及所需的GetRow)。當我遇到這個問題時,我正在尋找其他的東西,所以我沒有使用它,但其他人似乎對它有好運。您會注意到存在指向his blog的鏈接,您可能也會發現DataGrid相關的所有內容都很有用。

0


希望能夠幫助別人。
我會告訴的MVVM方式,在瀏覽:

<DataGrid Name="dg1" ItemsSource="{Binding Table}" AutoGenerateColumns="False" Margin="3" SelectionMode="Single" IsReadOnly="True" SelectedIndex="{Binding Path=SelectedIndex, Mode=TwoWay}"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Date" Binding="{Binding mydate}" MinWidth="100"></DataGridTextColumn> 
     <DataGridTextColumn Header="Count" Binding="{Binding Count}" MinWidth="100"></DataGridTextColumn> 
    </DataGrid.Columns> 

    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="SelectionChanged" SourceName="dg1" > 
      <i:InvokeCommandAction Command="{Binding DgSelectionChanged}" CommandParameter="{Binding ElementName=dg1}"/> 
     </i:EventTrigger> 

    </i:Interaction.Triggers>   
</DataGrid> 
現在

在視圖模型:
需要後,設置selectedIndex:添加,刪除等...和

private ICommand dgSelectionChanged; 
    /// <summary> 
    /// when the datagrid Selection Changes 
    /// </summary> 
    public ICommand DgSelectionChanged 
    { 
     get 
     { 
      return dgSelectionChanged ?? 
      (dgSelectionChanged = new RelayCommand<DataGrid>(dg1 => 
      { 
       // whatever you want when the Selection Changes 


       SelectedIndex= d 
       //select the item 
       if (dg1.SelectedIndex > -1) 
       { 
        dg1.Focus(); 
        dg1.CurrentCell = new DataGridCellInfo(dg1.Items[dg1.SelectedIndex], dg1.Columns[0]); 
       } 
      })); 
     } 
    } 

的方式,以選擇第一行加載控制之後,將其添加到視圖:

 <!-- select the row after control loaded --> 
     <i:EventTrigger EventName="Loaded" SourceName="dg1" > 
      <i:InvokeCommandAction Command="{Binding DgSelectionChanged}" CommandParameter="{Binding ElementName=dg1}"/> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 

謝謝,阿維。

0

The answer given by Gauss是正確的做法,但也有一些代碼,它是清晰的:

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e) 
{ 
    e.Row.Loaded += Row_Loaded; 
} 

void Row_Loaded(object sender, RoutedEventArgs e) 
{   
    var row = (DataGridRow) sender; 
    row.Loaded -= Row_Loaded; 
    DataGridCell cell = GetCell(dataGrid, row, 0); 
    if (cell != null) cell.Focus(); 
    dataGrid.BeginEdit();   
} 

static DataGridCell GetCell(DataGrid dataGrid, DataGridRow row, int column) 
{ 
    if (dataGrid == null) throw new ArgumentNullException("dataGrid"); 
    if (row == null) throw new ArgumentNullException("row"); 
    if (column < 0) throw new ArgumentOutOfRangeException("column"); 

    DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(row); 
    if (presenter == null) 
    { 
     row.ApplyTemplate(); 
     presenter = FindVisualChild<DataGridCellsPresenter>(row); 
    } 
    if (presenter != null) 
    { 
     var cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell; 
     if (cell == null) 
     { 
      dataGrid.ScrollIntoView(row, dataGrid.Columns[column]); 
      cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell; 
     } 
     return cell; 
    } 
    return null; 
} 

static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject 
{ 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     var visualChild = child as T; 
     if (visualChild != null) 
      return visualChild; 
     var childOfChild = FindVisualChild<T>(child); 
     if (childOfChild != null) 
      return childOfChild; 
    } 
    return null; 
} 

您檢索在DataGrid.LoadingRow事件的行,但細胞是尚未公佈。因此,您在Loaded事件中放置了一個處理程序,以等待此事件發生,然後您可以檢索該單元格並將焦點放在該事件上。

處理程序被刪除以避免新的觸發。

編輯會話也可以用dataGrid.BeginEdit()開始。

所有這些都在代碼隱藏中,因爲它屬於視圖。