c# - 自定义样式的 TextBox SelectionStart 始终为 0

标签 c# wpf textbox wpf-style

我有一个带有自定义样式的 TextBox 输入字段:

  <TextBox  Style="{StaticResource SettingsTextBoxHint}" KeyDown="textBoxInput_KeyDown" PreviewKeyDown="textBoxInput_PreviewKeyDown"  Name="TextBoxInput" Text="{Binding TextBoxInput, Mode=TwoWay}" Tag="{lex:LocText TypeAMessageHere}" VerticalScrollBarVisibility="Auto"  TextWrapping="Wrap"  FontSize="14" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Margin="0,0,33,0"/>

我添加了自定义样式:

<Style TargetType="{x:Type TextBox}" x:Key="SettingsTextBoxHint" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">

                <Border x:Name="Border"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="White"
                        Padding="1,2,5,2"
                        BorderBrush="{StaticResource PrimaryColor}"
                        ToolTip="{TemplateBinding ToolTip}">
                    <Grid>
                        <TextBox Text="{Binding Path=Text,
                                            RelativeSource={RelativeSource TemplatedParent}, 
                                            Mode=TwoWay,
                                            UpdateSourceTrigger=PropertyChanged}"
                                 x:Name="textSource" 
                                 Background="Transparent" 
                                 BorderBrush="Transparent"
                                 TextWrapping="{TemplateBinding TextWrapping}"
                                 Panel.ZIndex="2"
                                 FontSize="12">
                            <TextBox.Style>
                                <Style TargetType="{x:Type TextBox}">
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="TextBox">

                                                <Border x:Name="Border"
                                                        Background="Transparent"
                                                        BorderBrush="Transparent"
                                                        CornerRadius="0">
                                                    <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
                                                </Border>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>

                                </Style>
                            </TextBox.Style>
                        </TextBox>
                        <TextBox  Margin="0,3,0,0" BorderThickness="0" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
                            <TextBox.Style>
                                <Style TargetType="{x:Type TextBox}">
                                    <Setter Property="FontFamily" Value="{StaticResource RobotoRegularFont}" />
                                    <Setter Property="Foreground" Value="Transparent"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
                                            <Setter Property="Foreground" Value="#cccccc"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBox.Style>
                        </TextBox>
                    </Grid>
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter TargetName="textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=textSource}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

重点是使 TextBox 透明并添加通过 Tag 设置文本的提示功能。

一切都如我所愿。我遇到的问题是我正在编写一个新功能,其中我需要光标在 TextBox 中的位置。但是 SelectionStart 或 CaretIndex 总是返回 0 值。如果我删除我的样式,我会得到正确的值。

谁能告诉我我错过了什么?

最佳答案

问题是您正在 TextBox 中使用 TextBox。用户与内部文本框交互,其文本、插入符号位置等与外部文本框没有任何关系。

让我为你整理一下你的风格:

<Style x:Key="SettingsTextBoxHint"
       TargetType="{x:Type TextBox}"
       BasedOn="{StaticResource {x:Type TextBox}}">
  <Setter Property="BorderBrush"
          Value="{StaticResource PrimaryColor}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border x:Name="Border"
                BorderThickness="{TemplateBinding BorderThickness}"
                Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                Padding="{TemplateBinding Padding}">
          <Grid>
            <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
            <TextBlock x:Name="Hint"
                       Margin="3,1"
                       Text="{TemplateBinding Tag}"
                       FontStyle="Italic"
                       Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
                       Visibility="Hidden" />
          </Grid>
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Border"
                    Property="Background"
                    Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
            <Setter Property="Foreground"
                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
          </Trigger>
          <Trigger Property="Text" Value="">
            <Setter TargetName="Hint" Property="Visibility" Value="Visible"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

要在 TextBox 中找到光标位置,您可以使用 Mouse.GetPosition(your_text_box)。要获取文本中的 caret 位置,请使用 CaretIndex 属性。但是请注意,CaretIndex*不是* 依赖属性,因此它不会引发更改通知。因此,您不能绑定(bind)到它并期望更新绑定(bind)目标。

关于c# - 自定义样式的 TextBox SelectionStart 始终为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48323294/

相关文章:

c# - 除了调用 thread.Join() 之外,如何等待线程完成运行?

c# - 减少 C# 中的使用次数

wpf - 在WPF MVVM中使用行为?

wpf - TargetType 与元素类型不匹配

c# - 某处是否有 API 允许将一个邮政编码与邮政编码列表进行比较以查找哪个最近?

c# - 如何分配 ItemsSource 属性

asp.net - asp文本框控件的CSS

javascript - 如何从 javascript 更新输入文本?

c# - 如何在不使用 ajax 扩展或 Web 服务的情况下在文本框中提供自动完成功能?

c# - 在我的 ASP.NET 应用程序中的什么地方注册 IMemoryCache?