文本框有时光标丢失

时间:2015-08-14 08:36:46

标签: c# wpf xaml textbox controltemplate

我创建了一个自定义水印文本框,它从文本框中扩展而来。相同的控制模板如下所示。

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type controls:WaterMarkTextBox}">
            <ControlTemplate.Resources>
                <Storyboard x:Key="Storyboard1">
                    <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)"
                                                      Storyboard.TargetName="PART_FieldTextBlock">
                        <SplineThicknessKeyFrame KeyTime="0:0:0.15"
                                                 Value="0,0,10,0" />
                    </ThicknessAnimationUsingKeyFrames>
                </Storyboard>
                <Storyboard x:Key="Storyboard2">
                    <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)"
                                                      Storyboard.TargetName="PART_FieldTextBlock">
                        <SplineThicknessKeyFrame KeyTime="0:0:0.25"
                                                 Value="0,0,-500,0" />
                    </ThicknessAnimationUsingKeyFrames>
                </Storyboard>
            </ControlTemplate.Resources>
            <Grid x:Name="PART_GridControl"
                  ClipToBounds="True"
                  Height="{TemplateBinding Height}"
                  Width="{TemplateBinding Width}">
                <TextBlock x:Name="PART_PlaceHolderTextBlock"
                           Style="{StaticResource SWMLightTextBlockStyle}"
                           Foreground="#BDBBBB"
                           FontSize="{StaticResource SmallFontSize}"
                           Text="{TemplateBinding PlaceHolderText}"
                           VerticalAlignment="Center"
                           Margin="20,0,10,0" />
                <Border Name="border"
                        CornerRadius="0"
                        Padding="2"
                        BorderThickness="1"
                        BorderBrush="DeepSkyBlue">
                    <ScrollViewer x:Name="PART_ContentHost"/>
                </Border>
                <TextBlock x:Name="PART_FieldTextBlock"
                           HorizontalAlignment="Right"
                           Foreground="#BDBBBB"
                           Margin="0,0,-500,0"
                           Style="{StaticResource SWMLightTextBlockStyle}"
                           FontSize="{StaticResource SmallFontSize}"
                           TextWrapping="Wrap"
                           Text="{TemplateBinding FieldText}"
                           VerticalAlignment="Center" />
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

但是在键入文本框时会进入一个没有光标的情况,但我们可以输入它的概率为1/2字符。我想知道它是如何发生的。任何人都知道它是如何发生的?

1 个答案:

答案 0 :(得分:1)

你可以做两件事。第一个是覆盖SystemParameters属性使用反射像这样

void LocallyDisableMouseVanish()
    {
        foreach (var field in typeof(SystemParameters).GetFields(BindingFlags.NonPublic|BindingFlags.Static))
            if (field.Name.Contains("mouseVanish"))
                field.SetValue(null, false);
    }

将此方法称为“控制焦点”。

如果这不起作用意味着您可以尝试这样的事情覆盖Caret的风格像这样

 <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:WaterMarkTextBox}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="Storyboard1">
                        <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)"
                                                          Storyboard.TargetName="PART_FieldTextBlock">
                            <SplineThicknessKeyFrame KeyTime="0:0:0.15"
                                                     Value="0,0,10,0" />
                        </ThicknessAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="Storyboard2">
                        <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)"
                                                          Storyboard.TargetName="PART_FieldTextBlock">
                            <SplineThicknessKeyFrame KeyTime="0:0:0.25"
                                                     Value="0,0,-500,0" />
                        </ThicknessAnimationUsingKeyFrames>
                    </Storyboard>
                </ControlTemplate.Resources>
                <Grid x:Name="PART_GridControl"
                      ClipToBounds="True"
                      Height="{TemplateBinding Height}"
                      Width="{TemplateBinding Width}">
                    <TextBlock x:Name="PART_PlaceHolderTextBlock"
                               Style="{StaticResource SWMLightTextBlockStyle}"
                               Foreground="#BDBBBB"
                               FontSize="{StaticResource SmallFontSize}"
                               Text="{TemplateBinding PlaceHolderText}"
                               VerticalAlignment="Center"
                               Margin="20,0,10,0" />
                    <Border Name="border"
                            CornerRadius="0"
                            Padding="2"
                            BorderThickness="1"
                            BorderBrush="DeepSkyBlue">
                        <ScrollViewer x:Name="PART_ContentHost" />
                    </Border>
                    <TextBlock x:Name="PART_FieldTextBlock"
                               HorizontalAlignment="Right"
                               Foreground="#BDBBBB"
                               Margin="0,0,-500,0"
                               Style="{StaticResource SWMLightTextBlockStyle}"
                               FontSize="{StaticResource SmallFontSize}"
                               TextWrapping="Wrap"
                               Text="{TemplateBinding FieldText}"
                               VerticalAlignment="Center" />
                    <Canvas>
                        <Border x:Name="PART_Caret"
                                Visibility="Collapsed"
                                Canvas.Left="0"
                                Canvas.Top="0"
                                Width="5"
                                Height="25"
                                Background="Black"
                                BorderThickness="1">
                            <Border.Triggers>
                                <EventTrigger RoutedEvent="Border.Loaded">
                                    <BeginStoryboard>
                                        <Storyboard  x:Name="CaretStoryBoard"
                                                     RepeatBehavior="Forever">
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Background.Color"
                                                                          Duration="0:0:0:1"
                                                                          FillBehavior="HoldEnd">
                                                <ColorAnimationUsingKeyFrames.KeyFrames>
                                                    <DiscreteColorKeyFrame KeyTime="0:0:0.750"
                                                                           Value="Transparent" />
                                                    <DiscreteColorKeyFrame KeyTime="0:0:0.000"
                                                                           Value="Black" />
                                                </ColorAnimationUsingKeyFrames.KeyFrames>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Border.Triggers>
                        </Border>
                    </Canvas>
                </Grid>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="CaretBrush "
            Value="Transparent" />

在您的控制代码中添加此

 public override void OnApplyTemplate()
    {
        this.border = this.GetTemplateChild("PART_Caret") as Border;
        base.OnApplyTemplate();
    }

并添加此方法

 private void MoveCustomCaret()
    {
        var caretLocation = this.GetRectFromCharacterIndex(this.CaretIndex).Location;

        if (!double.IsInfinity(caretLocation.X))
        {
            Canvas.SetLeft(border, caretLocation.X);
        }

        if (!double.IsInfinity(caretLocation.Y))
        {
            Canvas.SetTop(border, caretLocation.Y);
        }
    }

最后调用此方法并设置边框的可见性

private void SWMTextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        MoveCustomCaret();
        border.Visibility = Visibility.Visible;
    }

也在TextChangedEvent

private void CustomTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        MoveCustomCaret();
    }

隐藏Lost_Focus_Event

中的可见性
private void SWMTextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        border.Visibility = Visibility.Hidden;
    }