2009-06-24 15 views

risposta

11

ci sono un paio di opzioni in Silverlight 2, il più semplice sarebbe quella di utilizzare un TextBlock dal momento che è sempre e solo in sola lettura.

Se hai bisogno di un TextBox, allora quello che devi fare è dargli uno stile diverso che non influisca sul grigio.

Per fare questo aprire la miscela. fare clic con il tasto destro sulla casella di testo e selezionare Modifica parti di controllo (modello) -> Modifica una copia ... Chiama il nuovo stile come preferisci.

Quindi si desidera modificare questo nuovo stile ed eliminare il bordo denominato "ReadOnlyVisualElement" ed eliminare lo storyboard che altera la proprietà di opacità di quel bordo.

Spero che questo aiuti.

Aggiunto Stile 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> 

otterrei l'anteprima di Blend, codifica quanto sopra a mano sarebbe una grande quantità di lavoro inutile.

+0

Non sto usando un TextBlock perché voglio ancora poter copiare Testo dalla casella di testo e incollarlo da qualche altra parte. Non ho Blend (sto usando Visual Web Developer 2008 Express) quindi non posso provare il tuo secondo suggerimento. – Struan

+3

+1 per TE GOTTA BE KIDDING ME! –

+0

5 anni dopo. ancora utile – Billatron

10

Nulla sembra funzionare nello xaml (come al solito), quindi la soluzione migliore che ho trovato è di creare una casella di testo di sola lettura senza la proprietà IsReadOnly.

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

Questo ha aiutato con un problema che ho cercato di creare una casella combinata di sola lettura. Nel mio caso ho dovuto anche gestire OnKeyUp con lo stesso codice per interrompere l'attivazione di un gestore di eventi KeyUp. – voiddog

+0

+1 per "come al solito" –

+0

Un altro +1 per "come al solito". Un problema con questo approccio è che ottieni il bordo e il segno di omissione quando fai clic sulla casella di testo. –

2

Ecco una versione avanzata della risposta di @ Struan.

Presumo che si desideri consentire Select all e Copy se si desidera una casella di testo di sola lettura. È necessario gestire i tasti da premere come Ctrl+A e Ctrl+C.

Declinazione di responsabilità: Questo non è un set completo di chiavi - potrebbe essere necessario aggiungerne altre, ma ciò consentirà la copia almeno.

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

Ed ecco un semplice stile che sto usando che indica all'utente che l'articolo è selezionabile, ma è più piccolo di una casella di testo tipico.

<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 funziona ancora :-( – MadSeb

3

Se si desidera solo un equivalente di un blocco di testo in HTML, che può essere selezionato (che per qualche motivo ancora Silverlight 4 è mancante) è possibile ridurre la risposta di Graeme leggermente:

<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> 

Potresti anche essere in grado di rimuovere gli stati disabilitati.

0

Ho trovato la soluzione di Simon_Weaver la più facile da implementare. L'unico cambiamento che ho fatto è stato controllare Key.Tab insieme a sinistra/destra/su/giù in modo da poter uscire dal campo. Ho creato la classe ReadOnlyTextBox e ho copiato il codice sopra. Poi ho aggiunto il controllo per Key.Tab e compilato.Poi ho cambiato il mio tag Xaml da

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

a

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

(rimuovere il riferimento IsEnabled e aggiungendo il colore di sfondo). Sembra e funziona esattamente come mi aspettavo.

Grazie Simon.

0

ho voluto per ridurre lo stile a nudo l'osso, e testato questo con Silverlight 4.0:

<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> 

E 'quasi un imbroglio, come dire: Hey silverligh, this textbox is a textblock! Si deve infine aggiungere qualcosa nel tag TextBlock, a riflettere meglio altre proprietà TextBox.

0

Fino a quando la definizione/comportamento/aspetto di un pulsante non cambia, un'altra soluzione più elegante consiste semplicemente nel modificare il TextBox in un pulsante. Cambia la proprietà 'Testo' in una proprietà 'Contenuto' per impostare il testo visualizzato, rimuovi l'impostazione 'IsReadOnly' e avrai l'effetto che desideri, credo (un controllo a scatola di testo piatta che supporta il testo e tutti i bordo, sfondo, proprietà di primo piano di una casella di testo senza il cambio di opacità [ingrigimento] e la seccatura di definire un nuovo stile).

Quando un utente tenta di interagire con questo controllo, le sue caratteristiche cambiano sull'evento click, ma senza un gestore eventi associato al pulsante, non ci sarà alcun impatto sulla tua interfaccia. In effetti, penso che il comportamento del pulsante predefinito faccia sembrare l'effetto "cool".

+0

Oh, dovrei aggiungere che devi quindi fare attenzione quando accedi al controllo come componente figlio per assicurarti che lo stai digitando su un Button piuttosto che su un TextBox, ma presumo che la maggior parte gli sviluppatori che fanno questa domanda lo capirebbero. – Epsilon3

Problemi correlati