sizes multi wpf xaml resize

multi - WPF: Establecer el ancho(y la altura) como un valor porcentual



view uwp (7)

Digamos que quiero que un TextBlock tenga su Width igual al Width del contenedor primario (es decir, se extienda de lado a lado) o un porcentaje de su Width contenedor principal, ¿cómo puedo lograr esto en XAML sin especificar valores absolutos?

Quiero hacer esto para que, si el contenedor Parent Container se expande más tarde (es '' Width increased''), sus ''Elementos secundarios'' también se expandan automáticamente. (básicamente, como en HTML y CSS)


Implementación IValueConverter se puede utilizar. La clase de convertidor que toma la herencia de IValueConverter toma algunos parámetros como el value (porcentaje) y el parameter (ancho de los padres) y devuelve el valor de ancho deseado. En el archivo XAML, el ancho del componente se establece con el valor deseado:

public class SizePercentageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (parameter == null) return 0.7 * value.ToDouble(); string[] split = parameter.ToString().Split(''.''); double parameterDouble = split[0].ToDouble() + split[1].ToDouble() / (Math.Pow(10, split[1].Length)); return value.ToDouble() * parameterDouble; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // Don''t need to implement this return null; } }

XAML:

<UserControl.Resources> <m:SizePercentageConverter x:Key="PercentageConverter" /> </UserControl.Resources> <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Width="{Binding Converter={StaticResource PercentageConverter}, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualWidth}" Height="{Binding Converter={StaticResource PercentageConverter}, ConverterParameter=0.6, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualHeight}"> .... </ScrollViewer>


La forma de estirarlo al mismo tamaño que el contenedor primario es usar el atributo:

<Textbox HorizontalAlignment="Stretch" ...

Esto hará que el elemento del cuadro de texto se extienda horizontalmente y llene todo el espacio principal horizontalmente (en realidad depende del panel principal que está utilizando, pero debería funcionar en la mayoría de los casos).

Los porcentajes solo se pueden usar con valores de celdas de cuadrícula, por lo que otra opción es crear una cuadrícula y colocar su cuadro de texto en una de las celdas con el porcentaje apropiado.


Normalmente, utilizaría un control de diseño integrado apropiado para su escenario (por ejemplo, use una cuadrícula como elemento principal si desea escalar en relación con el elemento principal). Si desea hacerlo con un elemento primario arbitrario, puede crear un ValueConverter, pero probablemente no será tan limpio como desee. Sin embargo, si realmente lo necesita, podría hacer algo como esto:

public class PercentageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }

Que se puede usar así, para obtener un cuadro de texto secundario al 10% del ancho de su lienzo principal:

<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300"> <Window.Resources> <local:PercentageConverter x:Key="PercentageConverter"/> </Window.Resources> <Canvas x:Name="canvas"> <TextBlock Text="Hello" Background="Red" Width="{Binding Converter={StaticResource PercentageConverter}, ElementName=canvas, Path=ActualWidth, ConverterParameter=0.1}"/> </Canvas> </Window>


Para cualquiera que obtenga un error como: la cadena ''2 *'' no puede convertirse a Longitud.

<Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="2*" /><!--This will make any control in this column of grid take 2/5 of total width--> <ColumnDefinition Width="3*" /><!--This will make any control in this column of grid take 3/5 of total width--> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition MinHeight="30" /> </Grid.RowDefinitions> <TextBlock Grid.Column="0" Grid.Row="0">Your text block a:</TextBlock> <TextBlock Grid.Column="1" Grid.Row="0">Your text block b:</TextBlock> </Grid>


Sé que no es Xaml, pero hice lo mismo con el evento SizeChanged del cuadro de texto:

private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e) { TextBlock textBlock = sender as TextBlock; FrameworkElement element = textBlock.Parent as FrameworkElement; textBlock.Margin = new Thickness(0, 0, (element.ActualWidth / 100) * 20, 0); }

El cuadro de texto parece tener un tamaño del 80% de su elemento primario (el margen derecho es 20%) y se estira cuando es necesario.


Yo uso dos métodos para el tamaño relativo. Tengo una clase llamada Relative con tres propiedades adjuntas To , WidthPercent y HeightPercent que es útil si quiero que un elemento sea un tamaño relativo de un elemento en cualquier parte del árbol visual y se siente menos hacky que el enfoque del convertidor, aunque use lo que funciona para tú, con quien estás feliz.

El otro enfoque es bastante más astuto. Agregue un ViewBox donde desee tamaños relativos dentro, luego dentro de eso, agregue un Grid en el ancho 100. Luego, si agrega un TextBlock con ancho 10 dentro de eso, obviamente es 10% de 100.

El ViewBox escalará la Grid acuerdo con el espacio que se le haya asignado, de modo que si es lo único en la página, la Grid se ampliará a todo su ancho y efectivamente, su TextBlock se escalará al 10% de la página.

Si no establece una altura en la Grid , se encogerá para ajustarse a su contenido, por lo que tendrá un tamaño relativamente grande. Deberá asegurarse de que el contenido no sea demasiado alto, es decir, que comience a cambiar la relación de aspecto del espacio dado al ViewBox sino que también comenzará a escalar la altura. Probablemente puedas evitar esto con un Stretch of UniformToFill .


Esta es una respuesta actualizada a mi publicación anterior del ''09 y que contenía información incorrecta. El siguiente ejemplo debería ser mejor:

Puede colocar los cuadros de texto dentro de una cuadrícula para hacer valores porcentuales en las filas o columnas de la cuadrícula y dejar que los cuadros de texto se llenen automáticamente a sus celdas principales (como lo harán de forma predeterminada). Ejemplo:

<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="2*" /> <ColumnDefinition Width="3*" /> </Grid.ColumnDefinitions> <TextBox Grid.Column="0" /> <TextBox Grid.Column="1" /> </Grid>

Esto hará # 1 2/5 del ancho, y # 2 3/5.

Publicación original con información incorrecta / incompleta

No creas que puedes hacer%, pero puedes hacerlo * :)

Ejemplo:

<TextBox width="2*"/> <TextBox width="3*"/>

Esto hará # 1 2/5 del ancho, y # 2 3/5.