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?
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.