Как выделить весь текст, когда текстовое поле редактирования в DataGridTemplateColumn получает фокус? - PullRequest
7 голосов
/ 14 апреля 2010

Я пытаюсь заставить DataGridTemplateColumn вести себя идентично TextColumn

  • когда ячейка переходит в режим редактирования (нажмите F2), пользователь может сразу же начать ввод нового значения
  • по умолчанию выбран существующий текстовый контент, так что вы можете легко установить новые значения

Получил первый сделанный; Однако выделение всего текста не работает. Как уже упоминалось в ряде сообщений, попытался подключиться к событию GotFocus и выделить весь текст в коде позади. Это работало для отдельного текстового поля; однако для Textbox, который является элементом редактирования для TemplateColumn, это не работает.

Есть идеи? Пример кода:

<Window.Resources>
            <Style x:Key="HighlightTextBoxStyle" TargetType="{x:Type TextBox}">
                <EventSetter Event="GotFocus" Handler="SelectAllText"/>
                <EventSetter Event="GotMouseCapture" Handler="SelectAllText"/>
                <Setter Property="Background" Value="AliceBlue"/>
            </Style>

            <DataTemplate x:Key="DefaultTitleTemplate">
                <TextBlock Text="{Binding Title}"/>
            </DataTemplate>
            <DataTemplate x:Key="EditTitleTemplate">
                    <TextBox x:Name="Fox"
                         FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"  
                         Text="{Binding Path=Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                         Style="{StaticResource HighlightTextBoxStyle}">
                    </TextBox>
            </DataTemplate>
        </Window.Resources>
        <DockPanel>
            <TextBox DockPanel.Dock="Top" x:Name="Test" Text="{Binding Path=(FocusManager.FocusedElement).Name, ElementName=MyWindow}" 
                     Style="{StaticResource HighlightTextBoxStyle}"/>
            <toolkit:DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
                <toolkit:DataGrid.Columns>
                    <toolkit:DataGridTemplateColumn Header="Templated Title" 
                        CellTemplate="{StaticResource DefaultTitleTemplate}"
                        CellEditingTemplate="{StaticResource EditTitleTemplate}" />

                    <toolkit:DataGridTextColumn Header="Title" Binding="{Binding Path=Title}" />
                </toolkit:DataGrid.Columns>
            </toolkit:DataGrid>
        </DockPanel>

Ответы [ 2 ]

6 голосов
/ 26 апреля 2011

Пропущено обновление поста с ответом ...

Проблема, по-видимому, заключается в том, что для пользовательского столбца сетки данных (он же DataGridTemplateColumn) сетка не имеет возможности узнать точный тип элемента управления для редактирования (который указывается с помощью DataTemplate и может быть любым). Для DataGridTextColumn тип элемента управления редактирования известен, и, следовательно, сетка может найти его и вызвать в нем SelectAll ().

Таким образом, чтобы достичь конечной цели для TemplateColumn, вам необходимо предоставить помощь. Я забыл, как я решил это в первый раз ... но вот кое-что, что я искал - подправил сегодня. Создание пользовательского деривации TemplateColumn с переопределением метода PrepareCellForEdit, как показано ниже (поменяйте местами текстовое поле с точным управлением редактирования).

public class MyCustomDataColumn : DataGridTemplateColumn
    {
        protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
        {
            var contentPresenter = editingElement as ContentPresenter;

            var editingControl = FindVisualChild<TextBox>(contentPresenter);
            if (editingControl == null)
                return null;

            editingControl.SelectAll();
            return null;
        }

        private static childItem FindVisualChild<childItem>(DependencyObject obj) 
    }

Вот реализация FindVisualChild .

XAML:

   <WPFTestBed:MyCustomDataColumn Header="CustomColumn"
                    CellTemplate="{StaticResource DefaultTitleTemplate}"
                    CellEditingTemplate="{StaticResource EditTitleTemplate}"/>
</DataGrid.Columns>

Много кода для досадных несоответствий.

0 голосов
/ 04 февраля 2015

Я знаю, что уже поздно, но я выбрал другой подход и творчески расширил класс TextBox. Мне не очень нравится использовать логическое значение для проверки того, что текст уже определен, но проблема в том, что все события выбора запускаются до того, как текст будет установлен из привязки, поэтому SelectAll () не имеет ничего для выбора! Этот класс, вероятно, полезен только в качестве шаблона редактирования в чем-то вроде DataGridTemplateColumn. Каждое решение, которое я нашел для этой проблемы, в значительной степени является взломом, так что я не слишком расстраиваюсь из-за этого ...:)

class AutoSelectTextBox : TextBox
{
    private bool _autoSelectAll= true;

    protected override void OnInitialized(EventArgs e)
    {
        // This will cause the cursor to enter the text box ready to
        // type even when there is no content.
        Focus();
        base.OnInitialized(e);
    }

    protected override OnKeyDown(System.Windows.Input.KeyEventArgs e)
    {
        // This is here to handle the case of an empty text box.  If
        // omitted then the first character would be auto selected when
        // the user starts typing.
        _autoSelectAll = false;
        base.OnKeyDown(e);
    }


    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        if (_autoSelectAll)
        {
            SelectAll();
            Focus();
            _autoSelectAll= false;
        }
        base.OnTextChanged(e);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...