I load the contents of a database (mdb) into a DataTable
object and display them in a DataGrid
so that I can edit them. As soon as I start editing a cell (pressing F2), the entire text is selected.
Is there a way to prevent this marking?
My DataGrid
markup:
<DataGrid VirtualizingStackPanel.VirtualizationMode="Standard" Height="750" Width="1920" CanUserResizeColumns="True" CanUserReorderColumns="False" CanUserResizeRows="False" RowHeight="25" FrozenColumnCount="1" x:Name="DataGrid1" CanUserAddRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" FontSize="13" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,120" SelectionUnit="CellOrRowHeader" SelectionMode="Extended">
<DataGrid.Columns>
<DataGridTextColumn Width="450" Header=" Column1 " Binding="{Binding Column1}">
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="MaxLength" Value="150"></Setter>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="120" Header=" Column2 " Binding="{Binding Column2}">
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="MaxLength" Value="10"></Setter>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="KeyDown" Handler="DATAGRID_Keydown" ></EventSetter>
</Style>
</DataGrid.RowStyle>
</DataGrid>
My C# Code:
private void DATAGRID_Keydown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab | e.Key == Key.F2)
{
DataGrid1.BeginEdit();
}
}
CodePudding user response:
As an alternative to adding a handler for PreparingCellEdit
in code-behind, you could create a behavior that encapsulates the code for moving the caret of the TextBox
in order to make it reusable across multiple views without copy-pasting the code for each instance.
You have to install the Microsoft.Xaml.Behaviors.Wpf NuGet package and create a behavior for DataGrid
. The behavior adds a handler to PreparingCellEdit
and sets the caret to the end. There is also an attached property which enables you to exclude columns from the behavior. By inverting the default value, you could disable the behavior by default and enable it explicitly for each column.
public class PrepareTextEditBehavior : Behavior<DataGrid>
{
public static readonly DependencyProperty MoveCaretToEndProperty = DependencyProperty.RegisterAttached(
"MoveCaretToEnd", typeof(bool), typeof(PrepareTextEditBehavior), new PropertyMetadata(true));
public static bool GetMoveCaretToEnd(DependencyObject obj)
{
return (bool)obj.GetValue(MoveCaretToEndProperty);
}
public static void SetMoveCaretToEnd(DependencyObject obj, bool value)
{
obj.SetValue(MoveCaretToEndProperty, value);
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreparingCellForEdit = OnPreparingCellForEdit;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.PreparingCellForEdit -= OnPreparingCellForEdit;
}
private static void OnPreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
if (!GetMoveCaretToEnd(e.Column))
return;
var textBox = (TextBox)e.EditingElement;
textBox.CaretIndex = textBox.Text.Length;
}
}
To use the behavior, simply add it to the data grid in the Interaction.Behaviors
tag.
<DataGrid ...>
<b:Interaction.Behaviors>
<local:PrepareTextEditBehavior/>
</b:Interaction.Behaviors>
<DataGrid.Columns>
<DataGridTextColumn ...>
<!-- ...column markup. -->
<!-- ...the behavior is applied here by default. -->
</DataGridTextColumn>
<DataGridTextColumn ...
local:PrepareTextEditBehavior.MoveCaretToEnd="False">
<!-- ...column markup. -->
<!-- ...the behavior is NOT applied here explicitly. -->
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
CodePudding user response:
you can use the PreparingCellForEdit
event for the DataGrid
:
XAML
<DataGrid ... PreparingCellForEdit="DataGrid_PreparingCellForEdit">
C# (It will place the cursor at the end of the current cell text)
private void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
((TextBox)e.EditingElement).SelectionStart = ((TextBox)e.EditingElement).Text.Length;
}
You can use use ((TextBox)e.EditingElement).SelectionStart = 0;
to place the cursor at the beginning of the original text of that cell.