2009-07-27 14 views
13

Ho questo TextBox. Questo TextBox si trova nel DataTemplate:wpf: selezionare il testo in TextBox con IsReadOnly = true?

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

e voglio permettere all'utente di selezionare tutto il testo al suo interno (facoltativamente facendo clic sulla casella di testo). E non voglio usare alcun codice dietro.

Come fare? Grazie in anticipo.

+0

Ho usato 'SelectAll()' e quindi consente di fare clic con il tasto destro del mouse e copiare il contenuto. – EricG

risposta

18

L'utilizzo della proprietà IsReadOnly anziché IsEnabled consente all'utente di selezionare il testo. Inoltre, se non dovrebbe essere modificato, un binding OneWay dovrebbe essere sufficiente.

L'idea di XAML non è quella di sostituire completamente il code-behind. La cosa più importante è che si prova ad avere solo codice specifico dell'interfaccia utente nel code-behind, non nella logica aziendale. Detto questo, selezionare tutto il testo è specifico per l'interfaccia utente e non fa male nel code-behind. Usa myTextBox.SelectAll() per quello.

+0

Bene, il problema è che questo si trova in un DataTemplate. E quello che so Gli eventi non possono essere utilizzati in DataTemplates. –

+0

Inoltre, sto cercando di utilizzare MVVM. È OK avere un codice specifico per l'interfaccia utente nel codice? Ad esempio, i miei pulsanti non hanno gestori di eventi Onclick, ma sono associati a ICommand direttamente in MVVM. –

+0

Se è solo specifico per l'interfaccia utente, è corretto inserirlo nel codice. Con MVVM, è raramente necessario, ma ciò non significa che non ne avrai mai bisogno. Inoltre, ci sono mezzi per ottenere i controlli generati da un datatemplate. Ad esempio, se hai un ItemsControl (Listbox ecc.), Puoi usare listBox.ItemContainerGenerator.ContainerFromItem (listBox.SelectedItem); – Botz3000

6

La rimozione di IsEnabled e l'impostazione di TextBox come ReadOnly consentirebbero di selezionare il testo ma interrompere l'immissione dell'utente.

IsReadOnly="True" 

L'unico problema con questo approccio è che, anche se non sarà in grado di digitare nel controllo TextBox sarà ancora guardare 'Abilitato'.

Per risolvere il problema (se si desidera?) È possibile aggiungere uno stile per schiarire il testo e scurire lo sfondo (per renderlo disattivato).

Ho aggiunto il seguente esempio con uno stile che farà scorrere la casella di testo tra un aspetto disattivato e abilitato.

<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

Una nota Ho appena scoperto (ovviamente si tratta di una vecchia questione, ma questo potrebbe aiutare qualcuno):

Se IsHitTestVisible=False quindi selezionando (e quindi Copia) è disabilitato.

0

leggermente modificata esempio - per abbinare lo stile di WinForms (non inventare il proprio nuovo stile)

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> 

e naturalmente il vostro testo deve avere impostato IsReadOnly = attributo "True".