2009-07-27 6 views
13

J'ai ce TextBox. Cette zone de texte est situé dans DataTemplate:wpf: Sélection du texte dans TextBox avec IsReadOnly = true?

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

et je veux permettre à l'utilisateur de sélectionner tout le texte à l'intérieur (en option en cliquant sur la zone de texte). Et je ne veux utiliser aucun code derrière.

Comment faire? Merci d'avance. L'utilisation de la propriété IsReadOnly au lieu de IsEnabled permet à l'utilisateur de sélectionner du texte.

+0

J'ai utilisé 'SelectAll()', puis il vous permet de faire un clic droit et de copier le contenu néanmoins. – EricG

Répondre

18

En outre, s'il ne doit pas être modifié, une liaison OneWay devrait suffire.

L'idée de XAML n'est pas de remplacer complètement le code-behind. Le plus important est que vous essayez d'avoir uniquement du code spécifique à l'interface utilisateur dans le code-behind, pas la logique métier. Cela étant dit, la sélection de tout le texte est spécifique à l'interface utilisateur et ne blesse pas dans le code-behind. Utilisez myTextBox.SelectAll() pour cela.

+0

Eh bien, le problème est que celui-ci est situé dans un DataTemplate. Et ce que je sais, les événements ne peuvent pas être utilisés dans DataTemplates. –

+0

Quoi de plus, j'essaie d'utiliser le MVVM. Est-il correct d'avoir un code spécifique à l'interface utilisateur dans le code? Par exemple, mes boutons n'ont pas de gestionnaires d'événements Onclick, mais ils sont liés directement à ICommand dans MVVM. –

+0

Si ce n'est spécifique à l'interface utilisateur, il est correct de le mettre dans le code derrière. Avec MVVM, c'est rarement nécessaire, mais cela ne signifie pas que vous n'en aurez jamais besoin. En outre, il existe des moyens d'obtenir des contrôles générés à partir d'un datatemplate. Par exemple, si vous avez un ItemsControl (Listbox etc.), vous pouvez utiliser listBox.ItemContainerGenerator.ContainerFromItem (listBox.SelectedItem); – Botz3000

6

Supprimer IsEnabled et définir TextBox comme ReadOnly vous permet de sélectionner le texte mais d'arrêter l'entrée de l'utilisateur.

IsReadOnly="True" 

Le seul problème avec cette approche est que même si vous ne serez pas en mesure de taper dans la zone de texte, il sera toujours « Activé ».

Pour contourner cela (si vous voulez?), Vous pouvez simplement ajouter un style pour éclaircir le texte et assombrir l'arrière-plan (pour le faire paraître désactivé).

J'ai ajouté l'exemple suivant avec un style qui balaiera la zone de texte entre un aspect désactivé et activé.

<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

Une note que je viens de découvrir (évidemment c'est une vieille question, mais cela pourrait aider quelqu'un):

Si IsHitTestVisible=False puis en sélectionnant (et donc copie) est également désactivé.

0

exemple modifié légèrement - faire correspondre le style de WinForms (pas inventer votre propre 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> 

Et bien sûr, votre zone de texte doit avoir IsReadOnly = "true" set.

Questions connexes