Xaml 在 TextBlock 和 TextBox 之间切换
Xaml switch between TextBlock and TextBox
我注意到当 Text
通过代码动态更改时,文本框非常慢并且会产生性能问题(我需要同时将 Text
连续更改为 10-15 个文本框时间),因此,作为一种解决方法,我创建了一个带有 TextBlock
和 TextBox
的自定义控件:
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>
我注意到当 Text
通过代码动态更改时,文本框非常慢并且会产生性能问题(我需要同时将 Text
连续更改为 10-15 个文本框时间),因此,作为一种解决方法,我创建了一个带有 TextBlock
和 TextBox
的自定义控件:
The
TextBlock
is used in almost all time.
TheTextBox
is used only when I need to edit theText
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>