我有一個綁定到可觀察集合的數據網格。 當用戶按下「添加按鈕」時,它會添加一個新行,我通過向observablecollection添加一個新元素來完成此操作。Datagrid將重點放在新添加的行上
我無法弄清楚如何使第一個單元格的新添加的行焦點,就好像我們正在編輯。我正在使用MVVM模式。
任何想法或建議嗎?
我有一個綁定到可觀察集合的數據網格。 當用戶按下「添加按鈕」時,它會添加一個新行,我通過向observablecollection添加一個新元素來完成此操作。Datagrid將重點放在新添加的行上
我無法弄清楚如何使第一個單元格的新添加的行焦點,就好像我們正在編輯。我正在使用MVVM模式。
任何想法或建議嗎?
嘗試捕獲DataGrid的LoadingRow
(或類似)事件。在行上執行SetFocus(e.Row)
(或類似)。這純粹是面向View的,所以它符合MVVM。
你想要做這樣的事情:
DataGridCell cell = GetCell(rowIndex, colIndex);
cell.Focus;
當然你需要一個難以捉摸GetCell()方法。來自MSFT的Vincent Sibal在this forum post中寫下了該方法(以及所需的GetRow)。當我遇到這個問題時,我正在尋找其他的東西,所以我沒有使用它,但其他人似乎對它有好運。您會注意到存在指向his blog的鏈接,您可能也會發現DataGrid相關的所有內容都很有用。
希望能夠幫助別人。
我會告訴的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>
謝謝,阿維。
什麼工作對我來說是的LoadingRow
,e.Row.Loaded
組合和以下鏈接的GetCell()
方法:
的DataGrid.LoadingRow
事件被稱爲細胞可通過GetCell
之前。但在DaraGridRow.Loaded
事件中,該單元格可用。
之後,您可以使用cell.Focus()
和DataGrid.BeginEdit()
。
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()
開始。
所有這些都在代碼隱藏中,因爲它屬於視圖。