2011-10-07 13 views
5

Ho un controllo utente che è un pulsante, con determinate caratteristiche, e ho una finestra che ha molti di questi pulsanti nel loro stile "normale". In questa stessa finestra, ho definito uno stile che sovrascrive alcune delle normali caratteristiche e ne voglio un mucchio (una specie di layout di tastiera). Quello che ho è un UniformGrid con 30 linee come questa:Elementi di ripetizione WPF

<wft:TouchButton Style="{StaticResource smallButtonStyle}" Click="TouchButton_Click" Tag="1">1</wft:TouchButton> 

<wft:TouchButton Style="{StaticResource smallButtonStyle}" Click="TouchButton_Click" Tag="2">2</wft:TouchButton> 

<wft:TouchButton Style="{StaticResource smallButtonStyle}" Click="TouchButton_Click" Tag="3">3</wft:TouchButton> 

dove l'unica cosa che cambia da una riga all'altra è il tag e valori contenuti. Qual è un modo migliore per disporre qualcosa di ripetitivo come questo, dove gli eventi Style e Click non devono essere presenti su ogni riga?

risposta

3

Immaginai che la risposta di Coline era spento la In cima alla sua testa, e gli ho dato un +1 per avermi indicato nella giusta direzione [GRAZIE], anche se non ha funzionato esattamente. Quello che ho finito con era vicino:

Nel costruttore per la finestra, per impostare le 30 linee quasi identiche:

var numberButtons = Enumerable.Range(1, 30) 
    .Select(r => new KeyValuePair<string,string>(r.ToString(), r.ToString())) 
    .ToList(); 
numberButtonItems.ItemsSource = numberButtons; 

Poi, questo XAML (si noti che "Caption" è una proprietà di il nostro controllo utente, in modo che non funziona per voi):

<ItemsControl Grid.Row="1" x:Name="numberButtonItems"> 
    <ItemsControl.ItemsPanel> 
    <!-- specify the panel that is the container for your items --> 
     <ItemsPanelTemplate> 
      <UniformGrid Rows="4" Columns="10" HorizontalAlignment="Left" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <!-- specify the template used to render each item --> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <wft:TouchButton Style="{StaticResource smallButtonStyle}" 
        Click="TouchButton_Click" 
        Tag="{Binding Key}" 
        Caption="{Binding Value}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
9

Un modo migliore sarebbe quello di creare un data-oggetto in codice che rappresenta i 30 elementi che si desidera nella vostra interfaccia utente, ad esempio:

class DataObject 
{ 
    string Tag {get;set;} 
    string Content {get;set;} 
} 

(sono sicuro che può venire con una migliore nome di quello!). Quindi creare i 30 articoli e li impostare come ItemsSource di un ItemsControl:

List<DataObject> myObjects = new List<DataObject>(); 
// populate here 
itemsControl.ItemsSource = myObjects 

tuo ItemsControl ha un DataTemplate che viene utilizzato per rendere ogni voce:

<ItemsControl x:Name="itemsControl"> 
    <!-- specify the panel that is the container for your items --> 
    <ItemsControl.ItemPanelTemplate> 
    <ItemPanelTemplate> 
     <UniformGrid/> 
    </ItemPanelTemplate> 
    </ItemsControl.ItemPanelTemplate> 
    <!-- specify the template used to render each item --> 
    <ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <wft:TouchButton Style="{StaticResource smallButtonStyle}" 
         Click="TouchButton_Click" 
         Tag="{Binding Tag}"/ 
         Content="{Binding Content}"> 
    </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+1

Ottengo "La proprietà attaccabile" ItemPanelTemplate "non è stata trovata nel tipo ItemsControl". Potrei averti preso alla lettera, ma ho incollato il codice, modificando (1) il nome ItemsControl, (2) inserendo gli attributi righe/colonne di UniformGrid e (3) correggendo la sintassi per Tag e Content. [P.S. Sono in .Net 3.5.] –

+0

Il codice precedente proveniva dalla memoria, quindi potrebbero esserci alcuni refusi. Penso che potrebbe essere ItemsPanelTemplate invece. – ColinE

2

un'alternativa (più di una XAML puro) la soluzione sarebbe quella di utilizzare uno stile predefinito BasedOn il vostro stile di nome, e l'aggiunta di un EventSetter per la ClickEvent :

<UniformGrid> 
    <UniformGrid.Resources> 
     <Style TargetType="{x:Type wft:TouchButton}" BasedOn="{StaticResource smallButtonStyle}"> 
      <EventSetter Event="Click" Handler="chButton_Click" /> 
     </Style> 
    </UniformGrid.Resources> 
    <wft:TouchButton Tag="1">1</wft:TouchButton> 
    <wft:TouchButton Tag="2">2</wft:TouchButton> 
    <wft:TouchButton Tag="3">3</wft:TouchButton> 
</UniformGrid> 

Un esempio generico completo per chiunque altro che attraversa questa risposta:

il codice esistente potrebbe essere simile a questo:

<Window x:Class="TestWPF.MainWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="MainWindow"> 
    <Window.Resources> 
     <Style x:Key="myButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Background" Value="Red" /> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <StackPanel> 
      <Button Style="{StaticResource myButtonStyle}" Content="1" Click="Button_Click" /> 
      <Button Style="{StaticResource myButtonStyle}" Content="2" Click="Button_Click" /> 
      <Button Style="{StaticResource myButtonStyle}" Content="3" Click="Button_Click" /> 
      <Button Style="{StaticResource myButtonStyle}" Content="4" Click="Button_Click" /> 
      <Button Style="{StaticResource myButtonStyle}" Content="5" Click="Button_Click" /> 
      <Button Style="{StaticResource myButtonStyle}" Content="6" Click="Button_Click" /> 
     </StackPanel> 
    </Grid> 
</Window> 

ed è possibile cambiare al seguente:

<Window x:Class="TestWPF.MainWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="MainWindow"> 
    <Window.Resources> 
     <Style x:Key="myButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Background" Value="Red" /> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <StackPanel> 
      <StackPanel.Resources> <!-- Adding style below will apply to all Buttons in the stack panel --> 
       <Style TargetType="{x:Type Button}" BasedOn="{StaticResource myButtonStyle}"> 
        <EventSetter Event="Click" Handler="Button_Click" /> 
       </Style> 
      </StackPanel.Resources> 
      <Button Content="1" /> 
      <Button Content="2" /> 
      <Button Content="3" /> 
      <Button Content="4" /> 
      <Button Content="5" /> 
      <Button Content="6" /> 
     </StackPanel> 
    </Grid> 
</Window> 
+0

Non ho scelto questo come risposta perché stavo cercando di evitare di avere 30 righe che erano quasi esattamente le stesse, ma +1 per mantenerlo puro xaml e dimostrare le risorse a livello di StackPanel, lasciando altri pulsanti da solo. –

+0

Questo ha fatto, esattamente, rispondere alla parte della domanda che era come impedire di ripetere lo stile e fare clic su ognuna delle molte linee. –

+0

@Kelly Cline - nessun problema ...Sono felice che tu sia riuscito a trovare una buona soluzione per te. Ho appena pensato di aggiungere questa risposta nel caso qualcuno si imbattesse in questo post. – Scott

Problemi correlati