2010-03-02 15 views
100

Ho un gruppo di pulsanti che dovrebbero agire come pulsanti di attivazione, ma anche come pulsanti di opzione in cui è possibile selezionare/premere un solo pulsante all'ora corrente. Inoltre, deve avere uno stato in cui nessuno dei pulsanti è selezionato/premuto.Come ottenere un gruppo di pulsanti di attivazione per agire come i pulsanti di opzione in WPF?

Il comportamento sarà simile alla barra degli strumenti di Photoshop, in cui zero o uno degli strumenti sono selezionati in qualsiasi momento!

Qualche idea su come questo possa essere implementato in WPF?

risposta

33

Il modo più semplice consiste nello stile di un ListBox per utilizzare ToggleButtons per il suo ItemTemplate

<Style TargetType="{x:Type ListBox}"> 
    <Setter Property="ListBox.ItemTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <ToggleButton Content="{Binding}" 
           IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
       /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Quindi è possibile utilizzare la proprietà SelectionMode di ListBox per gestire SingleSelect vs MultiSelect.

+0

grazie per aver condiviso! mi stavo chiedendo se questa è una buona pratica ... ma sembra essere ok .. – GorillaApe

+1

@LeeLouviere: Ti piacerebbe elaborare perché no? Non è un ottimo esempio di come usare il modello di oggetto? –

+2

È un cattivo esempio perché confondete visualizzazione e comportamento. Si modifica la visualizzazione tramite datatemplate ma si ha ancora il comportamento di una listbox e * non * il comportamento di una serie di pulsanti di commutazione/radio. L'interazione con la tastiera è strana. Una soluzione migliore sarebbe un ItemsControl con RadioButton, in stile ToggleButtons (vedi l'altra risposta più votata). – Zarat

4

è possibile inserire la griglia con i pulsanti di opzione e creare un pulsante come modello per i pulsanti radio. che solo programmaticaly rimuovere di controllo se non si desidera pulsanti per essere attivata

+0

Ma utilizzando i pulsanti di opzione c'è un modo per deselezionare tutti i pulsanti? Una volta selezionato, non vedo un modo semplice per deselezionarlo! –

+0

RadioButton ha una proprietà IsChecked, è possibile impostarlo su false nel codice quando è necessario –

+0

Grazie! Provalo –

3

Potete anche provare System.Windows.Controls.Primitives.ToggleButton

<ToggleButton Name="btnTest" VerticalAlignment="Top">Test</ToggleButton> 

Quindi scrivere codice contro la proprietà IsChecked per mimare l'effetto radiobutton

private void btnTest_Checked(object sender, RoutedEventArgs e) 
{ 
    btn2.IsChecked = false; 
    btn3.IsChecked = false; 
} 
+0

Questo non è molto generico e riutilizzabile ... per esempio, non è utilizzabile all'interno di 'ListBoxItem's. – ANeves

5

è possibile utilizzare sempre un evento generico sul clic del ToggleButton che imposta tutto ToggleButton.IsChecked in un controllo di gruppo (Grid, WrapPanel, ...) su false con l'aiuto di VisualTreeHelper; quindi ricontrolla il mittente. O qualcosa del genere.

private void ToggleButton_Click(object sender, RoutedEventArgs e) 
    { 
     int childAmount = VisualTreeHelper.GetChildrenCount((sender as ToggleButton).Parent); 

     ToggleButton tb; 
     for (int i = 0; i < childAmount; i++) 
     { 
      tb = null; 
      tb = VisualTreeHelper.GetChild((sender as ToggleButton).Parent, i) as ToggleButton; 

      if (tb != null) 
       tb.IsChecked = false; 
     } 

     (sender as ToggleButton).IsChecked = true; 
    } 
3

Ehi, in realtà ho sviluppato una soluzione per questo. È possibile sovrascrivere il modello di controllo per i pulsanti di opzione e posizionare i pulsanti di stampa in basso. Ho una soluzione implementata in una libreria open source qui:

http://code.google.com/p/phoenix-control-library/

È possibile ottenere la soluzione di lavoro per l'utilizzo out-of-the box o dare un'occhiata al codice sorgente lì.

Divertiti.

27
<RadioButton Content="Point" > 
    <RadioButton.Template> 
     <ControlTemplate> 
      <ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" 
          Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/> 
     </ControlTemplate> 
    </RadioButton.Template> 
</RadioButton> 

funziona per me, buon divertimento!

+0

So che questa non è la domanda. Ma cosa fare se il pulsante dovrebbe comportarsi come i pulsanti radio in cui uno deve essere sempre selezionato? – Karsten

+0

Alla mia risposta la mia stessa domanda: leggi la risposta di Uday Kiran :-) – Karsten

+0

Bello, questo agisce come SAME come pulsante Toggle. Fare clic per verificare e fare clic sullo stesso pulsante per deselezionare. e una volta che metto tutti i RadioButton in uno stesso gruppo, si comporta come i pulsanti Radio. Grazie a RoKK !!! – mili

248

Questo è il modo più semplice a mio parere.

<RadioButton Style="{StaticResource {x:Type ToggleButton}}" /> 

Divertiti! - Priceaw

+27

Questo dovrebbe essere selezionato risposta di gran lunga. Offre tutti i vantaggi di un radiobutton senza gli svantaggi legati al binding di alcuni controller. Ho provato per la prima volta a legare per separare il set di radiobutton invisibile, ma questo ha avuto un sovraccarico non necessario e si è concluso con un errore in cui tutti i pulsanti cliccati erano evidenziati ma non necessariamente controllati. –

+15

Oppure, se è necessario applicarlo a tutti i RadioButton all'interno di un elemento (es. Un 'Grid'), usare'