Reputation: 6368
Suppose I have a DataGrid. Suppose all the columns are TemplateColumns. When any cell gets focus I want it to go in EditMode.
What I have tried so far:
I have created a style for DataGridCell as follows:
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="GotFocus" Handler="DataGridCell_GotFocus" />
</Style>
In the Code-Behind of the Window :
private void DataGridCell_GotFocus(object sender, RoutedEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
{
cell.IsEditing = true;
}
}
Problems in above try :
I have to single click the cell to bring it in edit mode.
Upvotes: 5
Views: 5291
Reputation: 13679
Here is a trick to make it editable
BeginEdit()
method brings the current cell into edit mode.
sample
private void DataGridCell_GotFocus(object sender, RoutedEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
{
var parent = VisualTreeHelper.GetParent(cell);
while (parent != null && parent.GetType() != typeof(DataGrid))
{
parent = VisualTreeHelper.GetParent(parent);
}
DataGrid dGrid = parent as DataGrid;
dGrid.BeginEdit();
}
}
if you have access to the data grid then finding it may not be necessary
eg
private void DataGridCell_GotFocus(object sender, RoutedEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
{
dGrid.BeginEdit();
}
}
Update: FocusManager
trick
if focus is the only issue you can leverage FocusManager
by setting FocusManager.FocusedElement
. give it a try, it works without any code behind
.
sample
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}"
FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
note that I have set the FocusedElement
to the TextBox
by binding to self, this will bring the TextBox to focus once loaded (as it enters in edit mode)
Upvotes: 1
Reputation: 81253
On focus, cell goes into edit mode but the textBox doesn't have keyboard focus so next tab press will be eaten up by textBox and will get the focus.
As you mentioned you have to press Tab twice to move focus to next cell. What you can do is put focus on TextBox on loaded event:
XAML for dummy element:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" Loaded="TextBox_Loaded"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Code behind:
private void TextBox_Loaded(object sender, RoutedEventArgs e)
{
(sender as TextBox).Focus();
}
Of course you can move the handler to some base style for all your TextBoxes in dataGrid so you don't have to hook the handler for all cells.
In case you don't want to have handler, you can also do that using interactivity
triggers like defined here:
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Loaded">
<local:TakeFocusAction />
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
and behavior trigger action:
public class TakeFocusAction : TriggerAction<UIElement>
{
protected override void Invoke(object parameter)
{
AssociatedObject.Focus();
}
}
Upvotes: 6