【问题标题】:TextBox within DataTemplate, on GotFocus cannot assign SelectionStart?DataTemplate 中的 TextBox,在 GotFocus 上无法分配 SelectionStart?
【发布时间】:2011-11-24 19:41:51
【问题描述】:

我的文本框有一个逻辑,即在焦点上将选择开始移动到最后一个字符,以便编辑人员可以继续编写。

这与此完美配合:

    private void TextBox_GotFocus(object sender, EventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null) return;

        textBox.SelectionStart = textBox.Text.Length;
    }

    <Style TargetType="{x:Type TextBox}">
        <EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/>
    </Style>

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <TextBox Name="SomeTextBox" Text="{Binding Path=Pressure, UpdateSourceTrigger=PropertyChanged}" Padding="2,0,0,0" />
        <DataTemplate.Triggers>
            <Trigger SourceName="SomeTextBox" Property="IsVisible" Value="True">
                <Setter TargetName="SomeTextBox" Property="FocusManager.FocusedElement" Value="{Binding ElementName=SomeTextBox}"/>
            </Trigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

但是当我把它移到:

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <ContentControl Content="{Binding Path=Pressure, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ContentTemplate="{StaticResource DataGridTextBoxEdit}" />
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

还有一个可重复使用的模板:

    <DataTemplate x:Key="DataGridTextBoxEdit">
        <TextBox Name="TextBox" Text="{Binding Content, RelativeSource={RelativeSource AncestorType=ContentControl}}" Padding="2,0,0,0" />
        <DataTemplate.Triggers>
            <Trigger SourceName="TextBox" Property="IsVisible" Value="True">
                <Setter TargetName="TextBox" Property="FocusManager.FocusedElement" Value="{Binding ElementName=TextBox}"/>
            </Trigger>
        </DataTemplate.Triggers>
    </DataTemplate>

它刚刚停止工作。 GotFocus 事件触发,但我根本无法为 SelectionStart 分配任何内容,它只是不保存它。甚至尝试过硬编码:

    private void TextBox_GotFocus(object sender, EventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null) return;

        textBox.SelectionStart = 5;
    }

但是没有用。还需要注意的是 Text 是空的,此时只填充了 DataContext,但是由于 SelectionStart 没有采取任何措施(保存),这对我没有好处。

我做错了什么?

亲切的问候, 弗拉丹

【问题讨论】:

    标签: wpf textbox datatemplate contentcontrol textselection


    【解决方案1】:

    在 TextBox 获得焦点时,它还没有任何文本,这意味着处理程序在 DataGrid 分配值之前触发。解决此问题的一种方法是检查第一个文本更改,然后进行选择更改,例如

    private void TextBox_GotFocus(object sender, EventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null) return;
    
        var desc = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
        EventHandler handler = null;
        handler = new EventHandler((s, _) =>
            {
                desc.RemoveValueChanged(textBox, handler);
                textBox.SelectionStart = textBox.Text.Length;
            });
        desc.AddValueChanged(textBox, handler);
    }
    

    (此代码可能不是很干净,使用风险自负)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 2021-08-31
      • 2012-11-15
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多