2010-12-08 5 views
1

Im assez Noob dans WPF mais im essayant sérieusement de le maîtriser: pWPF Étiquette à textBox

Ive essayé de créer un contrôle où une étiquette/TextBlock est affiché, mais une fois que l'utilisateur passe/clique sur le contrôle, un La zone de texte est affichée à la place afin que la valeur puisse être modifiée. Ce que j'ai essayé essaye de lier la propriété Visible à un booléen dans le code-behind, qui est mis à jour en utilisant des délégués pour MouseOver et MouseLeave et Got/LostFocus, mais cela n'a pas fonctionné. Aussi j'ai essayé d'employer un style simple qui a lié aussi la propriété Visible au booléen dans le code-derrière ... n'a pas fonctionné non plus. En fin de compte, je suivais ce que WPF: Label to TextBox when selected a suggéré, en utilisant un ControlTemplate et un déclencheur, comme celui-ci:

<Style x:Key="TransformerBox" TargetType="{x:Type TextBox}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsMouseOver" Value="true"> 
          <Setter Property="Visibility" Value="Visible"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Et:

<Canvas x:Name="CnvCantidad" Grid.Row="2" Grid.Column="1"> 
     <TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="16" Canvas.Top="8" Width="16" 
       x:Name="TxtCantidad" Style="{StaticResource TransformerBox}" Height="23" Visibility="Visible"/> 
     <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="0" Canvas.Left="16" Canvas.Top="6" 
       x:Name="LblCantidad"/> 
    </Canvas> 

Mais dans tous les cas expliqué précédemment, la zone de texte n'a jamais été visible, peu importe ce que :/

Comment est-ce que je devrais créer le ControlTemplate afin que le TextBox soit visible lorsque l'utilisateur survole le Label/TextBlock?

Répondre

6

Edité le style d'une étiquette un peu pour faire une zone de texte apparaît lorsque IsMouseOver est T rue. C'est mieux que deux contrôles pour la réutilisation.

<Style x:Key="EditableLabelStyle" TargetType="{x:Type Label}"> 
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Padding" Value="5"/> 
    <Setter Property="HorizontalContentAlignment" Value="Left"/> 
    <Setter Property="VerticalContentAlignment" Value="Top"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Label}"> 
       <Grid> 
        <TextBox Name="textBox" 
          Grid.ZIndex="1" 
          Padding="1,3,0,0" 
          Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Label}}, Path=Content, UpdateSourceTrigger=PropertyChanged}" 
          Opacity="0"/> 
        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> 
         <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </Border> 
       </Grid> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" Value="true"> 
         <Setter TargetName="textBox" Property="Opacity" Value="1"/> 
        </Trigger> 
        <Trigger Property="IsEnabled" Value="false"> 
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

utiliser comme ceci

<Label Style="{StaticResource EditableLabelStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Content="0" Canvas.Left="16" Canvas.Top="6" 
     x:Name="LblCantidad"/> 
+0

Votre style l'a fait! Merci beaucoup :) – Machinarius

0

Il y a plusieurs façons de le faire.

D'une certaine façon, cela masque la TextBox jusqu'à ce que vous passiez la souris sur l'étiquette ou la TextBox (sinon la souris ne survole plus l'étiquette lorsque la zone de texte apparaît). Vous pourriez avoir à modifier, mais vous devriez obtenir l'idée (notez qu'il ne cache pas vraiment l'étiquette, juste affiche TextBox dessus):

<Canvas x:Name="CnvCantidad" Grid.Row="2" Grid.Column="1"> 
     <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="0" Canvas.Left="16" Canvas.Top="6" 
      x:Name="LblCantidad"/> 
     <TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="16" Canvas.Top="8" Width="16" 
      x:Name="TxtCantidad" Height="23"> 
      <TextBox.Style> 
       <Style TargetType="{x:Type TextBox}"> 
        <Setter Property="Visibility" Value="Collapsed" /> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding ElementName=LblCantidad, Path=IsMouseOver}" Value="True"> 
          <Setter Property="Visibility" Value="Visible" /> 
         </DataTrigger> 
         <DataTrigger Binding="{Binding ElementName=TxtCantidad, Path=IsMouseOver}" Value="True"> 
          <Setter Property="Visibility" Value="Visible" /> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </TextBox.Style> 
     </TextBox> 
    </Canvas> 
+0

ne fonctionnait pas, la zone de texte n'a jamais été visible :( – Machinarius

+0

Est-ce que ça marche si vous mettez cela sur une fenêtre entièrement nouvelle (à l'intérieur de la grille)? –

+0

Non, ne semble pas fonctionner même dans une grille – Machinarius

0

Si vous avez affaire à booléens et la visibilité que vous devriez considérer un ValueConverter.

Voici un exemple sur la manière de lier un booléen (IsTextVisible) dans votre modèle et de le mapper avec la visibilité réduite ou visible.

XAML:

<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="16" 
    Canvas.Top="8" Width="16" 
    x:Name="TxtCantidad" Style="{StaticResource TransformerBox}" Height="23" 
    Visibility="{Binding IsTextVisible, 
       Converter={StaticResource BoolToVisibilityConverter}}"/> 

Code ValueConverter:

public class BoolToVisibilityConverter : IValueConverter 
{ 
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     bool isVisible = Convert.ToBoolean(value); 

     return isVisible ? Visibility.Visible : Visibility.Collapsed; 
    } 

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

vous devez également importer l'espace de noms de conversion dans votre XAML

xmlns:converter="clr-namespace:Foo.Converter" 

et lui attribuer une clé

<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/> 

EDIT:

Si vous liant directement au code sous-jacent pour vos besoins, vous pouvez définir le DataContext pour la fenêtre dans le XAML cette façon

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

également faire Assurez-vous de lier une propriété

public bool IsTextVisible {get;set;} 

Dans le à long terme, vous voulez examiner les sujets suivants:

  1. Data Binding in WPF
  2. MVVM in WPF
+0

va essayer votre liaison, bien que j'ai déjà essayé quelque chose de similaire, merci :) – Machinarius

+0

je l'ai mis en œuvre de manière incorrecte ou il ne fonctionne pas :(La zone de texte était toujours derrière l'étiquette – Machinarius

+0

@Drknezz recherche la propriété Panel.ZIndex, qui contrôle dans quel ordre relatif les contrôles sont affichés, il suffit d'en affecter un plus haut au contrôle qui devrait être en avant. Aussi, si vous rencontrez des problèmes de liaison, il est bon de démarrer en mode débogage et de vérifier la fenêtre de sortie - toutes les erreurs de liaison sont affichées ici. – BrokenGlass

0

Vous pouvez le faire en réglant le ContentTemplate dans un trigger ou en définissant la zone de texte comme une ressource et la mise à l'aide d'un trigger.Check cet échantillon

<Label Height="30" BorderBrush="Gray" BorderThickness="1"> 
    <Label.Resources> 
     <TextBox x:Key="ContenTextBoxt" HorizontalAlignment="Stretch"/> 
    </Label.Resources> 
    <Label.Style> 
     <Style TargetType="{x:Type Label}"> 
      <Setter Property="Padding" 
            Value="0" /> 
       <Setter Property="HorizontalContentAlignment" 
            Value="Stretch" /> 
       <Setter Property="VerticalContentAlignment" 
            Value="Stretch" /> 
       <Setter Property="Content" 
            Value="No mouse over" /> 
      <Style.Triggers> 
       <Trigger Property="IsMouseOver" 
              Value="True"> 
        <Setter Property="Content" Value="{StaticResource ContenTextBoxt}" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Label.Style> 
    </Label>