2010-04-17 19 views
8

Supongamos que tiene una ventana con varios botones, como Ok/Cancelar o Sí/No/Cancelar. Todos los botones deben tener el mismo ancho. Obviamente, esto podría hacerse simplemente adivinando un número y cableando todos ellos a ese número.Botones WPF ancho igual/recomendado

¿Hay una manera mejor de hacerlo, una que tenga en cuenta los tamaños preferidos/recomendados (qué tan amplio debe ser un botón Ok de todos modos? Esta no es una pregunta retórica, ¡de hecho no sé la respuesta!), qué necesita el texto del título más largo, qué sucede si aumenta el tamaño de la fuente, etc.

+0

Por favor intente no codificar el tamaño de la interfaz de usuario y tal. Es una mala práctica tener en cuenta la internacionalización y (en menor medida ahora que WPF usa 'unidades independientes de resolución') varias pantallas de tamaño y DPI. Tenemos paneles de disposición disponibles para su uso. Ellos son buenos. –

+0

Se supone que los botones son 50dlu x 23dlu. WPF no admite unidades de diálogo; entonces estás bastante atascado. –

Respuesta

9

Hay varias maneras de hacer esto:

1) utilizar una cuadrícula de diseño. Cada Botón tiene su propia Columna, que es de tamaño Estrella. De esta manera, todas las columnas son del mismo tamaño:

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 
    <Button Grid.Column="0">Yes</Button> 
    <Button Grid.Column="1">No</Button> 
    <Button Grid.Column="2">Cancel</Button> 
</Grid> 

2) Usted puede tener un artículo como "tamaño maestro" y obligar a la anchura de todos los demás a la anchura de este aparato.

<StackPanel Orientation="Horizontal"> 
    <Button Name="MasterButton" Width="100">Yes</Button> 
    <Button> 
     <Button.Width> 
      <Binding ElementName="MasterButton" Path="Width"/> 
     </Button.Width> 
     No 
    </Button> 
</StackPanel> 

EDIT: En código real, es probable que tenga width = "Auto". Como los otros anchos se basan en el "ancho maestro", se debe elegir el botón con el ancho más ancho (el más ancho).

+0

+1 para recomendar el uso de paneles en su primera sugerencia, pero estoy realmente en contra de los tamaños de interfaz de usuario de codificación dura. –

+0

En el segundo caso, esto fue para demostrar que el enlace está funcionando. –

+5

¿No sería una buena solución una red uniforme? – henon

0

En el caso más general, desea crear un estilo en su sección, luego aplique este estilo como desee. Ahora cuando cambias el estilo, todos los botones cambian.

O bien, puede cambiar el contenido del botón para que se ajuste automáticamente al texto.

+0

Gracias. Pero, corríjame si estoy equivocado, pero no haciendo un botón de autoescala en el texto, ¿se rompe el requisito de que todos los botones tengan el mismo ancho? Y, ¿no es la solución de estilo, solo una forma particular de implementar 'adivinar un número y conectar todos los botones a ese número'? – rwallace

+0

Ah ... entiendo tu requerimiento ahora, lo siento! Daniel tiene una respuesta mucho mejor, entonces. – Dave

2

De acuerdo con las pautas de interacción de MS User Experience para Windows 7 y Windows Vista (p61), las dimensiones estándar para los botones de comando son 50x14 DLU de tamaño real (75x23 píxeles). Las pautas sugieren además que "intente trabajar con [estos] anchos y alturas predeterminados". Obviamente, si necesita más ancho para ajustarse a una etiqueta clara, tome más ancho.

+0

Se supone que los botones son 50x14 unidades de diálogo. Tu conversión a píxeles es incorrecta; al menos en mi computadora donde uso 'Georgia 14pt'. Es por eso que existen unidades de diálogo, por lo que la gente deja de usar tamaños de píxeles. –

4

Utilice un control "maestro", al igual que en la respuesta de Daniel, pero se unen a la "ActualWidth" atributo en lugar de "Ancho":

<StackPanel Orientation="Horizontal"> 
    <Button Name="MasterButton">Yes</Button> 
    <Button> 
     <Button.Width> 
      <Binding ElementName="MasterButton" Path="ActualWidth"/> 
     </Button.Width> 
     No 
    </Button> 
</StackPanel> 

De esta manera, el valor se toma del control maestro durante la ejecución tiempo, después de ancho mínimo y máximo y todos los demás cálculos de diseño se han tenido en cuenta. La vinculación a "Ancho" se une a lo que sea que ponga en el atributo en tiempo de compilación, que puede no ser el ancho que realmente se usa.

Además, la unión se puede escribir más corto como

<Button Width="{Binding ElementName=MasterButton, Path=ActualWidth}"/> 
7

Otro, quizás más simple, manera de hacer esto es utilizar la propiedad SharedSizeGroup en las clases ColumnDefinition y RowDefinition.

Las columnas (y las filas) en una cuadrícula WPF pueden redimensionarse automáticamente para ajustarse a sus contenidos: cuando se utiliza SharedSizeGroup, las columnas con el mismo nombre de grupo comparten su lógica de cambio de tamaño.

El Xaml se vería algo como esto ...

<Grid Grid.IsSharedSizeScope="True"> 

    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition SharedSizeGroup="Buttons" /> 
     <ColumnDefinition SharedSizeGroup="Buttons" /> 
     <ColumnDefinition SharedSizeGroup="Buttons" /> 
    </Grid.ColumnDefinitions> 

    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 

    <Button Grid.Column="1" 
      HorizontalAlignment="Stretch" 
      VerticalAlignment="Center" 
      Content="Ok" 
      Margin="4" /> 

    <Button Grid.Column="2" 
      HorizontalAlignment="Stretch" 
      VerticalAlignment="Center" 
      Content="Cancel" 
      Margin="4" /> 

    <Button Grid.Column="3" 
      HorizontalAlignment="Stretch" 
      VerticalAlignment="Center" 
      Content="Long Button Caption" 
      Margin="4" /> 
</Grid> 
0

Estas respuestas son grandes si usted tiene un número fijo o diseño fijo para los botones, pero si como yo, hay una serie dinámica de botones que vienen de una unión y la contenida en un ItemsControl entonces esto no es factible. Pero hay una manera simple y todavía implica utilizar la propiedad de tamaño compartido de Grid.

DataTemplate:

<DataTemplate x:Key="ODIF.Mapping"> 
    <Button HorizontalContentAlignment="Left" Background="#FFEEEEEE" BorderBrush="#FFBDBDBD"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" SharedSizeGroup="PluginButtonsWidth"/> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto" SharedSizeGroup="PluginButtonsIconHeight"/> 
       <RowDefinition Height="Auto" SharedSizeGroup="PluginButtonsNameHeight"/> 
      </Grid.RowDefinitions> 
      <Image Width="32" Height="32" Source="{Binding PluginIcon}" RenderOptions.BitmapScalingMode="HighQuality"/> 
      <TextBlock Grid.Row="1" Text="{Binding PluginName}"/> 
     </Grid> 
    </Button> 
</DataTemplate> 

contenedor principal:

<ItemsControl ItemsSource="{Binding MappingPlugins, ElementName=page}" ItemTemplate="{StaticResource ODIF.Mapping}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel Grid.IsSharedSizeScope="True"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

En esencia el contenido del botón puede ser en sí mismo un ceñidor que luego puede colocar sus etiquetas e iconos como sea necesario, pero a pesar de los botones no residen en la misma cuadrícula (cada uno es suyo) la cuadrícula puede compartir el tamaño siempre que establezca la propiedad del contenedor raíz (ItemsControl) de Grid.IsSharedSizeScope en True.

Esto obligará a la red de contenido de cada botón para tener el mismo tamaño exacto basado en el más grande sin tener que tienen los mismos botones en una cuadrícula predefinida.

Cuestiones relacionadas