WPF: CellEditingTemplate how can I set focus on the inner control by double click or on click

11,890

Solution 1

I find a way to resolve this problem, and here is my code.

<Window x:Class="MultiLineEditDataGrid.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MultiLineEditDataGrid"
    Title="MainWindow" Height="350" Width="525">
<Grid DataContext="{Binding Source={x:Static Application.Current}, Path=CompanyManager}">
    <Grid.RowDefinitions>
        <RowDefinition Height="270"/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
    <DataGrid ItemsSource="{Binding Companies}" CanUserAddRows="False" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <DataTemplate x:Key="cellTemplate">
                <TextBlock Text="{Binding Description}"/>
            </DataTemplate>
            <DataTemplate x:Key="cellEditingTemplate">
                <local:MultiLineTextBox x:Name="multiLineTxt" Text="{Binding Description}"/>
                <DataTemplate.Triggers>
                    <Trigger SourceName="multiLineTxt" Property="IsVisible" Value="True">
                        <Setter TargetName="multiLineTxt" Property="FocusManager.FocusedElement" Value="{Binding ElementName=multiLineTxt}"/>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Company" Binding="{Binding Name}"/>
            <DataGridTemplateColumn Header="Description" 
                                    CellTemplate="{StaticResource cellTemplate}" 
                                    CellEditingTemplate="{StaticResource cellEditingTemplate}"/>
        </DataGrid.Columns>
    </DataGrid>
    <Button Grid.Row="1" Content="Add" Command="{Binding AddCommand}"/>
</Grid>

Solution 2

I don't know why but the previous answer didn't work in my case. I found and alternative solution here http://madcoderspeak.blogspot.ca/2010/04/set-keyboard-focus-when-user-begins.html

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <StackPanel>
            <TextBox x:Name="editCommentTextBox" Text="{Binding Comment, Mode=TwoWay}"
                     FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}">
            </TextBox>
            <Label Content="{Binding Text, ElementName=editCommentTextBox, Converter={StaticResource CharCounterConverter}}"/>
         </StackPanel>
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
Share:
11,890
yafeya
Author by

yafeya

Super Man

Updated on June 25, 2022

Comments

  • yafeya
    yafeya almost 2 years

    I wrote a usercontrol of DataGrid with CellEditingTemplate. The DataTemplate of this editing-Template is a TextBox, and the cursor will go into the textbox by three times click, what can i do, if i want set the cursor on the textbox by double click or one click?

    Here is my code:

    <Window x:Class="MultiLineEditDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MultiLineEditDataGrid"
        Title="MainWindow" Height="350" Width="525">
    <Grid DataContext="{Binding Source={x:Static Application.Current}, Path=CompanyManager}">
        <Grid.RowDefinitions>
            <RowDefinition Height="270"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <DataGrid ItemsSource="{Binding Companies}" CanUserAddRows="False" AutoGenerateColumns="False">
            <DataGrid.Resources>
                <DataTemplate x:Key="cellTemplate">
                    <TextBlock Text="{Binding Description}"/>
                </DataTemplate>
                <DataTemplate x:Key="cellEditingTemplate">
                    <local:MultiLineTextBox Text="{Binding Description}"/>
                </DataTemplate>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Company" Binding="{Binding Name}"/>
                <DataGridTemplateColumn Header="Description" 
                                        CellTemplate="{StaticResource cellTemplate}" 
                                        CellEditingTemplate="{StaticResource cellEditingTemplate}"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button Grid.Row="1" Content="Add" Command="{Binding AddCommand}"/>
    </Grid>
    

    MultiLineTextBox is the TextBox which i inherit from textbox, and override OnKeyDown method.

    MultiLineTextBox's code:

    public class MultiLineTextBox : TextBox
    {
        /// <summary>
        /// On Key Down.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown ( KeyEventArgs e )
        {
            base.OnKeyDown ( e );
            string oldText = Text;
            ModifierKeys keys = Keyboard.Modifiers;
            if ( e.Key == Key.Enter )
            {
                if ( ( Keyboard.Modifiers & ModifierKeys.Control ).Equals ( ModifierKeys.Control ) )
                {
                    int index = SelectionStart;
                    oldText = oldText.Insert ( index, Environment.NewLine );
                    Text = oldText;
                    Select ( index + 1, 0 );
                    e.Handled = true;
                }
                else
                {
                    e.Handled = false;
                }
            }
            else if ( e.Key == Key.Escape )
            {
                Text = oldText;
                e.Handled = false;
            }
        }
    }
    
  • John Melville
    John Melville over 11 years
    Simpler than the accepted answer and worked well for me. Many thanks.