尝试创建允许文本选择的 WPF 标签模板时出现格式问题
我需要允许选择只读屏幕中显示的文本。
我们的一位开发人员提出的一个简单解决方案是使用 TextBox
而不是 Label 或 TextBlock,具有以下样式:
<Style x:Key="ControlData" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="TextWrapping" Value="Wrap" />
<!-- unrelated properties ommitted -->
</Style>
我不喜欢在那里使用 TextBox 的想法,除其他外,因为它迫使我使用 Binding Mode=OneWay
作为只读属性,所以我试图定义一个可以应用于标签以获得相同结果的样式:
<Style x:Key="SelectableLabel" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<TextBox Style="{StaticResource ControlData}"
Text="{Binding Path=Content, Mode=OneWay,
RelativeSource={RelativeSource FindAncestor,
AncestorType=Label}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
问题是,我的一些绑定已设置 StringFormat
,但该设置已丢失。
- 有没有办法保持外部绑定的格式?
- 我应该以不同的方式创建我的模板/绑定吗?
- 有没有比这更好的完全不同的方法?
- 我应该停止挑剔并使用文本框吗?
I have a requirement to allow selecting the text displayed in read only screens.
A simple solution one of our developers came up with is using a TextBox
instead of a Label or TextBlock, with the following style:
<Style x:Key="ControlData" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="TextWrapping" Value="Wrap" />
<!-- unrelated properties ommitted -->
</Style>
I don't like the idea of using a TextBox there, among other things because it forces me to use Binding Mode=OneWay
for read-only properties, so I was trying to define a Style that I can apply to a label to get the same result:
<Style x:Key="SelectableLabel" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<TextBox Style="{StaticResource ControlData}"
Text="{Binding Path=Content, Mode=OneWay,
RelativeSource={RelativeSource FindAncestor,
AncestorType=Label}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is, some of my bindings have StringFormat
set, and that is lost.
- Is there a way to keep the formatting of the outer binding?
- Should I create my template/binding differently?
- Is there a whole different approach that's better than this?
- Should I stop with the nitpicking and go with the TextBox?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为使用标签并覆盖控件模板是个好主意。最后,这就是 WPF 中控制逻辑和布局分离的目的,您应该利用它来获得更清晰、更易于理解的 xaml 代码。
您是否尝试使用 TemplateBinding 代替普通 Binding ?我不确定这是否会保留外部绑定,但这是建议在数据模板中使用的绑定。
您还应该看一下 ContentPresenter 类,尽管我不确定它是否适用于此处,因为您的内部文本框仅具有字符串类型的 Text 属性...
编辑:
我解决了这个问题,虽然它比我想象的更复杂...
创建样式如下:
ContentToTextConverter 定义如下:
如何使用的示例:
找到比这更好的解决方案会很好,但是对于此刻它应该按预期工作。
I think it's a good idea to use a Label and override the control template. At the end this is what the separation of Control logic and layout in WPF is for and you should make use of it to have a cleaner, more understandable xaml code.
Did you try using a TemplateBinding instad of normal Binding? I'm not sure if this will preserve the outer binding, but it's the recommended Binding to use in DataTemplates.
You should also take a look at the ContentPresenter class, although I'm not sure if it's applicable here, since your inner text box only has a Text property of type string...
Edit:
I solved the problem, although it was more complicated then I thought...
Create the style as following:
The ContentToTextConverter is defined as following:
Example of how to use:
It would be nice to find a nicer solution than this, but for the moment it should work as expected.
确实。
Definitely.