14

I have this TextBox. This TextBox is located in DataTemplate:

<DataTemplate x:Key="myTemplate">
    <TextBox  Text="{Binding Path=FullValue, Mode=TwoWay}" IsEnabled="False"  />
       ...

and I want to allow User to select the whole text inside it (optionally by clicking on the Textbox). And I don't want to use any code behind.

How to do that? Thanks in advance.

theSpyCry
  • 12,073
  • 28
  • 96
  • 152
  • I used `SelectAll()` and then it enables you to rightclick and copy the content nevertheless. – EricG Jan 15 '15 at 12:01

4 Answers4

21

Using the IsReadOnly property instead of IsEnabled allows the user to select text. Also, if it shouldn't be edited, a OneWay binding should be enough.

The idea of XAML isn't to completely replace code-behind. Most important is that you try to have only UI-specific code in the code-behind, not business logic. That being said, selecting all text is UI-specific and doesn't hurt in the code-behind. Use myTextBox.SelectAll() for that.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • Well the problem is that this one is located in a DataTemplate. And what I know Events cannot be used in DataTemplates. – theSpyCry Jul 27 '09 at 07:25
  • What more, I'm trying to use the MVVM. Is it OK to have a UI specific code in code behind ? For example, my buttons doesn't have Onclick event handlers, but they are bind to ICommand directly in the MVVM. – theSpyCry Jul 27 '09 at 07:26
  • If it's only UI-specific, it's ok to put it into the code behind. With MVVM, it's rarely necessary, but that doesn't mean you'll never need it. Also, there are means to obtain controls generated from a datatemplate. For example, if you have an ItemsControl (Listbox etc.), you can use listBox.ItemContainerGenerator.ContainerFromItem(listBox.SelectedItem); – Botz3000 Jul 27 '09 at 07:35
  • Alright, that's what I need. Thank you. Your answers are really well-taken. – theSpyCry Jul 27 '09 at 07:38
7

One note I just discovered (obviously this is an old question but this might help someone):

If IsHitTestVisible=False then selecting (and therefore Copy) is also disabled.

Dave Lowther
  • 408
  • 6
  • 13
6

Removing IsEnabled and setting the TextBox as ReadOnly would allow you to select the text but stop user input.

IsReadOnly="True" 

The only issue with this approach is that although you won't be able to type in the TextBox it will still look 'Enabled'.

To get round that (if you want to?) you can just add a style to lighten the text and darken the background (to make it look disabled).

I've added the following example with a style that will flick the textbox between a disabled and enabled look.

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
    <Style TargetType="{x:Type TextBox}">

        <Style.Triggers>
            <Trigger Property="IsReadOnly" Value="True">
                <Setter Property="Background" Value="LightGray" />
            </Trigger>
            <Trigger Property="IsReadOnly" Value="True">
                <Setter Property="Foreground" Value="DarkGray" />
            </Trigger>
            <Trigger Property="IsReadOnly" Value="False">
                <Setter Property="Background" Value="White" />
            </Trigger>
            <Trigger Property="IsReadOnly" Value="False">
                <Setter Property="Foreground" Value="Black" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <TextBox Height="23" Margin="25,22,133,0" IsReadOnly="True" Text="monkey"  Name="textBox1" VerticalAlignment="Top" />
    <Button Height="23" Margin="25,51,133,0" Name="button1" VerticalAlignment="Top" Click="button1_Click">Button</Button>
</Grid>

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        textBox1.IsReadOnly = !textBox1.IsReadOnly;
    }
Andy Clarke
  • 3,234
  • 5
  • 39
  • 66
0

Slightly modified example - to match style of WinForms (not invent your own new style)

By adding <Window.Resources> after <Window> and before <Grid> will make your text box behave like normal winforms textbox.


<Window x:Class="..." Height="330" Width="600" Loaded="Window_Loaded" WindowStartupLocation="CenterOwner">

<Window.Resources>
    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="IsReadOnly" Value="True">
                <Setter Property="Background" Value="LightGray" />
            </Trigger>
            <Trigger Property="IsReadOnly" Value="False">
                <Setter Property="Background" Value="White" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>

And of course your textbox must have IsReadOnly="True" attribute set.

TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62