2009-07-27 10 views
13

Mam ten TextBox. Ten TextBox znajduje się w DataTemplate:wpf: Wybór tekstu w TextBox za pomocą IsReadOnly = true?

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

i chcę, aby umożliwić użytkownikowi wybrać cały tekst wewnątrz niego (opcjonalnie klikając pola tekstowego). I nie chcę używać żadnego kodu .

Jak to zrobić? Z góry dziękuję.

+0

Użyłem 'SelectAll()', a następnie pozwala ci na kliknięcie i skopiowanie zawartości mimo wszystko. – EricG

Odpowiedz

18

Użycie właściwości IsReadOnly zamiast IsEnabled pozwala użytkownikowi wybrać tekst. Ponadto, jeśli nie powinno się tego edytować, wystarczy powiązanie OneWay.

Ideą XAML nie jest całkowita zamiana kodu z tyłu. Najważniejsze jest to, że próbujesz mieć tylko kod specyficzny dla UI w kodowaniu, a nie logice biznesowej. Biorąc to pod uwagę, zaznaczenie całego tekstu jest specyficzne dla interfejsu i nie boli w kodzie z tyłu. Użyj myTextBox.SelectAll() do tego.

+0

Problem polega na tym, że ten znajduje się w DataTemplate. I co wiem Zdarzenia nie mogą być używane w DataTemplates. –

+0

Co więcej, próbuję użyć MVVM. Czy to w porządku, aby mieć kod w interfejsie użytkownika? Na przykład moje przyciski nie mają programów obsługi zdarzeń Onclick, ale są one powiązane z ICommand bezpośrednio w MVVM. –

+0

Jeśli jest to tylko specyficzne dla UI, można umieścić go w kodzie. W przypadku MVVM rzadko jest to konieczne, ale to nie znaczy, że nigdy go nie potrzebujesz. Istnieją również środki do uzyskania kontroli generowanych z datatemplate. Na przykład, jeśli masz ItemsControl (Listbox itp.), Możesz użyć listBox.ItemContainerGenerator.ContainerFromItem (listBox.SelectedItem); – Botz3000

6

Usunięcie IsEnabled i ustawienie TextBox jako ReadOnly pozwoli Ci wybrać tekst, ale zatrzymać wprowadzanie danych przez użytkownika.

IsReadOnly="True" 

Jedyny problem z tym podejściem jest to, że mimo, że nie będzie mógł wpisać w polu tekstowym będzie nadal wyglądają „Włączone”.

Aby to obejść (jeśli chcesz?) Możesz po prostu dodać styl, aby rozjaśnić tekst i przyciemnić tło (aby wyglądał na wyłączony).

Dodałem następujący przykład ze stylem, który będzie poruszał pole tekstowe między wyłączonym a włączonym wyglądem.

<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; 
    } 
4

Jedna uwaga Właśnie odkryłem (oczywiście jest to stara sprawa, ale może to komuś pomóc):

Jeśli IsHitTestVisible=False następnie wybierając (a więc Kopiuj) jest również wyłączona.

0

nieco zmodyfikowany przykład - aby dopasować styl WinForms (nie wymyślać nowe własny styl)

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> 

i oczywiście musi mieć IsReadOnly tekstowe = „True” atrybut ustawiony.