2009-06-24 7 views

Antwort

11

Es gibt ein paar Optionen in Silverlight 2, die einfachste einen Textblock zu verwenden, wäre da, dass immer nur Read-only ist.

Wenn Sie eine TextBox benötigen, dann müssen Sie ihr einen anderen Stil geben, der den Grau-Effekt nicht beeinflusst.

Um dies zu tun öffnen Sie blend. Klicken Sie mit der rechten Maustaste auf Ihre TextBox und wählen Sie "Kontrollelemente bearbeiten" (Vorlage) -> "Kopie bearbeiten ...". Rufen Sie den neuen Stil auf, was immer Sie möchten.

Anschließend möchten Sie diesen neuen Stil bearbeiten und den Rahmen mit dem Namen "ReadOnlyVisualElement" löschen und das Storyboard löschen, mit dem die Opazitätseigenschaft des Rahmens geändert wird.

Hoffe, das hilft.

addiert Art XAML

<Style x:Key="ReadOnlyStyle" TargetType="TextBox"> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="Background" Value="#FFFFFFFF"/> 
     <Setter Property="Foreground" Value="#FF000000"/> 
     <Setter Property="Padding" Value="2"/> 
     <Setter Property="BorderBrush"> 
      <Setter.Value> 
       <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
        <GradientStop Color="#FFA3AEB9" Offset="0"/> 
        <GradientStop Color="#FF8399A9" Offset="0.375"/> 
        <GradientStop Color="#FF718597" Offset="0.375"/> 
        <GradientStop Color="#FF617584" Offset="1"/> 
       </LinearGradientBrush> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="TextBox"> 
        <Grid x:Name="RootElement"> 
         <vsm:VisualStateManager.VisualStateGroups> 
          <vsm:VisualStateGroup x:Name="CommonStates"> 
           <vsm:VisualState x:Name="Normal"/> 
           <vsm:VisualState x:Name="MouseOver"> 
            <Storyboard> 
             <ColorAnimationUsingKeyFrames Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"> 
              <SplineColorKeyFrame KeyTime="0" Value="#FF99C1E2"/> 
             </ColorAnimationUsingKeyFrames> 
            </Storyboard> 
           </vsm:VisualState> 
           <vsm:VisualState x:Name="Disabled"> 
            <Storyboard> 
             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity"> 
              <SplineDoubleKeyFrame KeyTime="0" Value="1"/> 
             </DoubleAnimationUsingKeyFrames> 
            </Storyboard> 
           </vsm:VisualState> 
           <vsm:VisualState x:Name="ReadOnly"> 
            <Storyboard> 
            </Storyboard> 
           </vsm:VisualState> 
          </vsm:VisualStateGroup> 
          <vsm:VisualStateGroup x:Name="FocusStates"> 
           <vsm:VisualState x:Name="Focused"> 
            <Storyboard> 
             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity"> 
              <SplineDoubleKeyFrame KeyTime="0" Value="1"/> 
             </DoubleAnimationUsingKeyFrames> 
            </Storyboard> 
           </vsm:VisualState> 
           <vsm:VisualState x:Name="Unfocused"> 
            <Storyboard> 
             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity"> 
              <SplineDoubleKeyFrame KeyTime="0" Value="0"/> 
             </DoubleAnimationUsingKeyFrames> 
            </Storyboard> 
           </vsm:VisualState> 
          </vsm:VisualStateGroup> 
          <vsm:VisualStateGroup x:Name="ValidationStates"> 
           <vsm:VisualState x:Name="Valid"/> 
           <vsm:VisualState x:Name="InvalidUnfocused"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> 
              <DiscreteObjectKeyFrame KeyTime="0"> 
               <DiscreteObjectKeyFrame.Value> 
                <Visibility>Visible</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </vsm:VisualState> 
           <vsm:VisualState x:Name="InvalidFocused"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> 
              <DiscreteObjectKeyFrame KeyTime="0"> 
               <DiscreteObjectKeyFrame.Value> 
                <Visibility>Visible</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen"> 
              <DiscreteObjectKeyFrame KeyTime="0"> 
               <DiscreteObjectKeyFrame.Value> 
                <System:Boolean>True</System:Boolean> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </vsm:VisualState> 
          </vsm:VisualStateGroup> 
         </vsm:VisualStateManager.VisualStateGroups> 
         <Border x:Name="Border" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1"> 
          <Grid> 
           <Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1"> 
            <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}"/> 
           </Border> 
          </Grid> 
         </Border> 
         <Border x:Name="DisabledVisualElement" IsHitTestVisible="False" Opacity="0" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}"/> 
         <Border x:Name="FocusVisualElement" Margin="1" IsHitTestVisible="False" Opacity="0" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}"/> 
         <Border x:Name="ValidationErrorElement" Visibility="Collapsed" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1"> 
          <ToolTipService.ToolTip> 
           <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"> 
            <ToolTip.Triggers> 
             <EventTrigger RoutedEvent="Canvas.Loaded"> 
              <BeginStoryboard> 
               <Storyboard> 
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible"> 
                 <DiscreteObjectKeyFrame KeyTime="0"> 
                  <DiscreteObjectKeyFrame.Value> 
                   <System:Boolean>true</System:Boolean> 
                  </DiscreteObjectKeyFrame.Value> 
                 </DiscreteObjectKeyFrame> 
                </ObjectAnimationUsingKeyFrames> 
               </Storyboard> 
              </BeginStoryboard> 
             </EventTrigger> 
            </ToolTip.Triggers> 
           </ToolTip> 
          </ToolTipService.ToolTip> 
          <Grid Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12" Background="Transparent"> 
           <Path Fill="#FFDC000C" Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z"/> 
           <Path Fill="#ffffff" Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8"/> 
          </Grid> 
         </Border> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

würde ich die Vorschau von Mischung erhalten, die Codierung der oben von Hand würde eine große Menge unnötiger Arbeit sein.

+0

Ich verwende keinen TextBlock, weil ich immer noch Text aus dem Textfeld kopieren und an anderer Stelle einfügen kann. Ich habe keine Mischung (ich benutze Visual Web Developer 2008 Express), also kann ich nicht Ihren zweiten Vorschlag versuchen. – Struan

+3

+1 für SIE GOTTA BE KIND ME! –

+0

5 Jahre später. immer noch hilfreich – Billatron

10

Nichts scheint in der XAML zu funktionieren (wie üblich), also ist die beste Lösung, die ich mir ausgedacht habe, ein Textfeld ohne die Eigenschaft IsReadOnly selbst zu schreiben.

public class ReadOnlyTextBox : TextBox 
{ 
    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     e.Handled = true; 
     base.OnKeyDown(e); 
    } 
} 
+1

Dies half mit einem Problem, das ich versuchte, eine Readonly Combobox zu machen. In meinem Fall musste ich auch den OnKeyUp mit demselben Code behandeln, um zu verhindern, dass ein KeyUp-Ereignishandler ausgelöst wird. – voiddog

+0

+1 für 'wie üblich' –

+0

Weitere +1 für 'wie üblich'. Ein Problem bei diesem Ansatz besteht darin, dass Sie den Rahmen und die Einfügemarke erhalten, wenn Sie auf die Textbox klicken. –

2

Hier ist eine erweiterte Version von @ Struan's Antwort.

Ich nehme an, Sie möchten Select all und Copy zulassen, wenn Sie eine schreibgeschützte Textbox wollen. Sie müssen Tasten drücken wie Ctrl+A und Ctrl+C.

Haftungsausschluss: Dies ist kein vollständiger Satz von Schlüsseln - Sie müssen möglicherweise mehr hinzufügen, aber dies wird zumindest für die Kopie ermöglichen.

public class ReadOnlyTextBox : TextBox 
{ 
    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down) 
     { 
      base.OnKeyDown(e); 
      return; 
     } 

     if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control || 
      (Keyboard.Modifiers & ModifierKeys.Apple) == ModifierKeys.Apple) 
     { 
      if (e.Key == Key.A || e.Key == Key.C) 
      { 
       // allow select all and copy! 
       base.OnKeyDown(e); 
       return; 
      } 
     } 

     e.Handled = true; 
     base.OnKeyDown(e); 
    } 
} 

Und hier ist eine einfache Art Ich bin mit, dass der Benutzer anzeigt, dass das Element auswählbar ist, aber kleiner als ein typisches Textbox.

<Style TargetType="my:ReadOnlyTextBox"> 
    <Setter Property="BorderThickness" Value="0"/> 
    <Setter Property="Padding" Value="3,0,3,0"/> 
    <Setter Property="Background" Value="Transparent"/> 
</Style> 
+0

hmm Backspace funktioniert immer noch :-( – MadSeb

3

Wenn Sie nur ein Äquivalent eines Textblocks in HTML, die ausgewählt werden können (die aus irgendeinem Grund auch Silverlight 4 fehlt) Sie können leicht Graeme Antwort verkürzen:

<Style x:Key="ReadOnlyStyle" TargetType="TextBox"> 
    <Setter Property="BorderThickness" Value="0"/> 
    <Setter Property="Background" Value="#FFFFFFFF"/> 
    <Setter Property="Padding" Value="2"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="TextBox"> 
       <Grid x:Name="RootElement"> 
        <vsm:VisualStateManager.VisualStateGroups> 
         <vsm:VisualStateGroup x:Name="CommonStates"> 
          <vsm:VisualState x:Name="Normal"/> 
          <vsm:VisualState x:Name="MouseOver"/> 
          <vsm:VisualState x:Name="Disabled" /> 
          <vsm:VisualState x:Name="ReadOnly"/> 
         </vsm:VisualStateGroup> 
         <vsm:VisualStateGroup x:Name="FocusStates"> 
          <vsm:VisualState x:Name="Focused"> 
           <Storyboard> 
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity"> 
             <SplineDoubleKeyFrame KeyTime="0" Value="1"/> 
            </DoubleAnimationUsingKeyFrames> 
           </Storyboard> 
          </vsm:VisualState> 
          <vsm:VisualState x:Name="Unfocused"> 
           <Storyboard> 
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity"> 
             <SplineDoubleKeyFrame KeyTime="0" Value="0"/> 
            </DoubleAnimationUsingKeyFrames> 
           </Storyboard> 
          </vsm:VisualState> 
         </vsm:VisualStateGroup> 
        </vsm:VisualStateManager.VisualStateGroups> 
        <Border x:Name="Border" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1"> 
         <Grid> 
          <Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1"> 
           <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}"/> 
          </Border> 
         </Grid> 
        </Border> 
        <Border x:Name="DisabledVisualElement" IsHitTestVisible="False" Opacity="0" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}"/> 
        <Border x:Name="FocusVisualElement" Margin="1" IsHitTestVisible="False" Opacity="0" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Sie können die deaktivierten Status möglicherweise sogar entfernen.

0

Ich fand @ Simon_Weaver die Lösung am einfachsten zu implementieren. Die einzige Änderung, die ich vorgenommen habe, war, nach Key.Tab zu suchen, zusammen mit links/rechts/oben/unten, damit ich aus dem Spielfeld springen konnte. Ich habe die Klasse ReadOnlyTextBox erstellt und den obigen Code kopiert. Dann habe ich den Check für Key.Tab hinzugefügt und kompiliert.Als nächstes änderte ich meine Xaml Tag aus

<TextBox ... IsEnabled="False" /> 

zu

<MyNameSpace:ReadOnlyTextBox ... Background="LightGray" /> 

(die IsEnabled Referenz Entfernen und Hinzufügen der Hintergrundfarbe). Es sieht und funktioniert genau so, wie ich es erwartet habe.

Danke Simon.

0

Ich wollte den Stil auf blanken Knochen und getestet dies mit Silverlight 4.0 reduzieren:

<Style x:Key="ReadOnlyStyle" TargetType="TextBox"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="TextBox"> 
       <TextBlock Text="{TemplateBinding Text}" TextAlignment="{TemplateBinding TextAlignment}" /> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Es ist fast ein Betrüger, wie wenn man sagt: Hey silverligh, this textbox is a textblock! Sie sollten schließlich fügen Sie etwas im Textblock-Tag, zu besser widerspiegeln andere TextBox-Eigenschaften.

0

Bis sich die Definition/das Verhalten/Aussehen einer Schaltfläche ändert, ist eine andere elegantere Lösung, einfach Ihre TextBox in eine Schaltfläche zu ändern. Ändern Sie die Eigenschaft 'Text' in eine Eigenschaft 'Inhalt', um den angezeigten Text festzulegen, entfernen Sie die Einstellung 'IsReadOnly', und Sie haben den gewünschten Effekt, glaube ich (ein flaches textboxähnliches Steuerelement, das Text und alle anderen unterstützt) Rand-, Hintergrund-, Vordergrundeigenschaften einer TextBox ohne die Opazitätsänderung [Ausgrauen] und die Schwierigkeit, einen neuen Stil zu definieren).

Wenn ein Benutzer versucht, mit diesem Steuerelement zu interagieren, werden die Features für das click-Ereignis geändert, ohne dass ein mit der Schaltfläche verknüpfter Ereignishandler Auswirkungen auf die Benutzeroberfläche hat. Tatsächlich denke ich, dass das Verhalten des Standard-Buttons den Effekt irgendwie "cool" erscheinen lässt.

+0

Oh, ich sollte hinzufügen, dass Sie dann vorsichtig sein müssen beim Zugriff auf das Steuerelement als Kind-Komponente, um sicherzustellen, dass Sie es zu einem Button anstelle eines TextBox eingeben, aber ich nehme am meisten Entwickler, die diese Frage stellen, würden dies verstehen. – Epsilon3

Verwandte Themen