当DataGridTemplateColumn中的编辑文本框获得焦点时,如何选择所有文本?

10

我正在尝试让DataGridTemplateColumn的行为与TextColumn相同:

  • 当单元格进入编辑模式(按F2键)时,用户可以立即开始输入新值
  • 默认情况下,现有文本内容被选中 - 这样您就可以轻松设置新值

第一个问题已经解决;但选择所有文本无效。正如一些帖子所提到的那样,尝试通过在代码后端侦听GotFocus事件并选择所有文本来解决此问题。这对于独立的文本框有效,但对于作为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>

据我所知,这个问题仍未解决。 - Dabblernl
@Dabblernl - 请尝试以下的“胶带修补”是否有效。 - Gishu
3个回答

8

没有更新帖子并附上答案...

问题似乎在于自定义数据网格列(也称为DataGridTemplateColumn)无法知道编辑控件的确切类型(通过DataTemplate指定,可以是任何内容)。对于DataGridTextColumn,编辑控件类型是已知的,因此网格可以找到它并调用SelectAll()。

因此,要实现TemplateColumn的最终目标,您需要提供帮助。我忘记了第一次解决它的方法...但是今天我搜索和调整出了以下内容:创建一个自定义的TemplateColumn派生类,并覆盖PrepareCellForEdit方法(将Textbox与您的确切编辑控件交换)

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>

为了解决一个烦人的不一致性需要写很多代码。


抱歉,我太晚了,无法给你奖金。非常感谢! - Dabblernl
@Dabblernl - 在遇见Mr.Skeet和朋友们之后,我停止了追求声望的行为 :) 只是很高兴能够帮助。 - Gishu
2
在我的情况下,我还必须将焦点设置到编辑文本框中。 editingControl.Focus(); editingControl.SelectAll(); - Honza Pačuta

0

我知道这已经晚了很多,但我采用了不同的方法并创造性地扩展了TextBox类。我不太喜欢使用布尔值来检查文本是否已定义,但问题是选择事件都在绑定设置文本之前触发,因此SelectAll()没有任何内容可供选择!这个类可能只在像DataGridTemplateColumn这样的编辑模板中有用。我找到的每个解决方案几乎都是一个hack,所以我对这个解决方案不感到太糟糕... :)

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);
    }
}

0

有点晚了...只是在这里放出来,以防有人可以用到

我有一个类似的需要,在编辑时反选(或选择全部)DataGridTextColumn中的文本

只需将该方法添加到DataGrid的PreparingCellForEdit事件中即可。

        DataGrid.PreparingCellForEdit += DataGrid_PreparingCellForEdit;

然后将(e.EditingElement as TextBox)分配给变量,并设置我的选项。
 private void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
    {
        var txtBox = e.EditingElement as TextBox;
        txtBox.Select(txtBox.Text.Length, 0); //to DeSelect all and place cursor at end
        txtBox.SelectAll(); // to selectall
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接