2011-10-07 11 views
5

Tengo un UserControl que es un botón, con ciertas características, y tengo una ventana que tiene varios de estos botones en su estilo "normal". En esta misma ventana, he definido un estilo que anula algunas de las características normales, y quiero un montón de ellas (algo así como un diseño de teclado). Lo que tengo es un UniformGrid con 30 líneas de este tipo:WPF elementos repetitivos

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

donde lo único que se cambia de una línea a otra es la etiqueta y los valores de contenido. ¿Cuál es una mejor manera de diseñar algo repetitivo como este, donde los eventos de Estilo y Clic no tienen que estar en cada línea?

Respuesta

3

Supuse que la respuesta de Coline estaba fuera de la arriba de su cabeza, y le di un +1 por apuntarme en la dirección correcta [GRACIAS], aunque no funcionó exactamente. Lo que terminó con la era estrecha:

En el constructor de la ventana, para establecer las 30 líneas casi idénticos:

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

Entonces, este xaml (tenga en cuenta que "Leyenda" es una propiedad de nuestro control de usuario, por lo que no va a funcionar para usted):

<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

Una mejor manera sería la creación de un objeto de datos de código que representa los 30 artículos que desee en la interfaz de usuario, por ejemplo:

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

(estoy seguro de que puede llegar a una mejor nombre que eso!). A continuación, crear sus 30 artículos y definirlas como ItemsSource de ItemsControl:

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

Su ItemsControl tiene una DataTemplate que se utiliza para representar cada elemento:

<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

obtengo "La propiedad acoplable 'ItemPanelTemplate' no se encontró en el tipo ItemsControl". Puede que te haya tomado demasiado literalmente, pero he pegado tu código, cambiando (1) el Nombre de control de elementos, (2) rellenando los atributos de filas/columnas de UniformGrid, y (3) corrigiendo la sintaxis de Etiqueta y contenido. [PD. Estoy en .Net 3.5.] –

+0

El código anterior era de memoria, por lo que podría haber algunos errores tipográficos. Creo que podría ser ItemsPanelTemplate en su lugar. – ColinE

2

una alternativa (más de un xaml puro) solución sería utilizar un estilo predeterminado BasedOn su estilo llamado, y añadiendo un EventSetter para 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 ejemplo genérico completa para cualquier otra persona que corre a través de esta respuesta:

su código existente podría tener este aspecto:

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

Y se puede cambiar a lo siguiente:

<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

No elegí esta como la respuesta porque estaba tratando de evitar tener 30 líneas que eran casi exactamente iguales, pero +1 por mantenerlo puro xaml y demostrar los recursos en el nivel de StackPanel, dejando los otros botones solo. –

+0

Esto, por cierto, respondía exactamente la parte de la pregunta que era cómo evitar repetir el Estilo y hacer clic en cada una de muchas líneas. –

+0

@Kelly Cline: no hay problema ...Me alegra que hayas podido encontrar una buena solución para ti. Pensé que agregaría esta respuesta en caso de que alguien se encuentre con esta publicación. – Scott

Cuestiones relacionadas