Xaml 在 TextBlock 和 TextBox 之间切换

Xaml switch between TextBlock and TextBox

我注意到当 Text 通过代码动态更改时,文本框非常慢并且会产生性能问题(我需要同时将 Text 连续更改为 10-15 个文本框时间),因此,作为一种解决方法,我创建了一个带有 TextBlockTextBox 的自定义控件:

The TextBlock is used in almost all time.
The TextBox is used only when I need to edit the Text inside the control with keyboard.

我的解决方案是更改模板并在控件获得焦点时使用 TextBox:

(Value 是一个 string 依赖项 属性)

<Style TargetType="{x:Type local:CustomControl1}">

    <Setter Property="Value" Value="Val"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Value}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                        <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                            <TextBox HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
                                     Text="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>  

但是当我点击控件时没有任何反应。
我认为问题在于 "focus state" 被传递到内部 TextBox,而控件丢失了 "focus state"。

有更好的方法来创建这样的自定义 "TextBox" 控件,或者有解决此问题的方法吗?

您不需要为此自定义控件,那只会增加不必要的开销。您要创建的仍然是一个 TextBox,具有 TextBox 的所有常见行为(焦点等)。您需要做的就是在模板未聚焦时将其更改为 TextBlock:

<Window.Resources>

    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="False">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBox}">
                            <TextBlock Text="{TemplateBinding Text}" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

</Window.Resources>

<StackPanel>
    <TextBox Text="Hello World" />
    <TextBox Text="Goodbye World" />
</StackPanel>