TextBox в DataTemplate, на GotFocus не может назначить SelectionStart? - PullRequest
0 голосов
/ 26 сентября 2011

У меня есть логика с моим текстовым полем, которая говорит, что при фокусе переместите начало выделения к последнему символу, чтобы редактор мог просто продолжать писать.

Это отлично сработало:

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

но не сработало.Также стоит отметить, что текст пуст, только DataContext заполняется на этом этапе, однако, так как SelectionStart ничего не берет (сохранение), мне это не поможет.

Что я делаю не так?

С уважением, Владан

1 Ответ

1 голос
/ 26 сентября 2011

В тот момент, когда 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);
}

(этот код может быть не очень чистым, используйте на свой страх и риск)

...