wpf - una - Cómo establecer el ancho máximo de la columna de cuadrícula según la ventana o el tamaño de pantalla en XAML
ajuste automático de escala en formularios windows forms c# (2)
Demasiado perezoso para escribirlo yo mismo, pero debería ser capaz de usar un convertidor matemático y vincularlo al ancho de las ventanas principales (ya sea por nombre o con una búsqueda de antepasados RelativeSource).
//I know I borrowed this from someone, sorry I forgot to add a comment from whom
public class ScaledValueConverter : IValueConverter
{
public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
{
Double scalingFactor = 0;
if (parameter != null)
{
Double.TryParse((String)(parameter), out scalingFactor);
}
if (scalingFactor == 0.0d)
{
return Double.NaN;
}
return (Double)value * scalingFactor;
}
public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
{
throw new Exception("The method or operation is not implemented.");
}
}
Tengo una cuadrícula de 3 columnas en una ventana con un GridSplitter en la primera columna. Quiero establecer el ancho máximo de la primera columna en un tercio de la ventana principal o el Width
página (o Width
ActualWidth
) y, si es posible, preferiría hacer esto en XAML.
Este es un ejemplo de XAML para jugar en XamlPad (o similar) que muestra lo que estoy haciendo.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" Width="200"/>
<ColumnDefinition x:Name="Column2" MinWidth="50" />
<ColumnDefinition x:Name="Column3" Width="{ Binding ElementName=Column1, Path=Width }"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="Green" />
<GridSplitter Grid.Column="0" Width="5" />
<Label Grid.Column="1" Background="Yellow" />
<Label Grid.Column="2" Background="Red" />
</Grid>
</Page>
Como puede ver, el ancho de la columna derecha está limitado al ancho de la primera columna, por lo que cuando desliza la columna izquierda usando el divisor, la columna derecha hace lo mismo :) Si desliza la columna izquierda hacia la derecha, con el tiempo se deslizará sobre la mitad de la página / ventana y hacia el lado derecho de la ventana, alejando las columnas 2 y 3.
Quiero evitar esto estableciendo el MaxWidth de la columna 1 en un tercio del ancho de la ventana (o algo así). Puedo hacer esto en el código con bastante facilidad, pero ¿cómo hacerlo en "XAML solamente"?
EDITAR: David Schmitt sugirió usar SharedSizeGroup en lugar de vinculante, lo cual es una sugerencia excelente. Mi código de muestra se vería así luego:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" SharedSizeGroup="ColWidth" Width="40"/>
<ColumnDefinition x:Name="Column2" MinWidth="50" Width="*" />
<ColumnDefinition x:Name="Column3" SharedSizeGroup="ColWidth"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="Green" />
<GridSplitter Grid.Column="0" Width="5" />
<Label Grid.Column="1" Background="Yellow" />
<Label Grid.Column="2" Background="Red" />
</Grid>
</Page>
Creo que el enfoque exclusivo de XAML es un tanto tortuoso, pero aquí hay una manera de hacerlo.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<!-- This contains our real grid, and a reference grid for binding the layout-->
<Grid x:Name="Container">
<!-- hidden because it''s behind the grid below -->
<Grid x:Name="LayoutReference">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- We need the border, because the column doesn''t have an ActualWidth -->
<Border x:Name="ReferenceBorder"
Background="Black" />
<Border Background="White" Grid.Column="1" />
<Border Background="Black" Grid.Column="2" />
</Grid>
<!-- I made this transparent, so we can see the reference -->
<Grid Opacity="0.9">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1"
MaxWidth="{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/>
<ColumnDefinition x:Name="Column2"
MinWidth="50" />
<ColumnDefinition x:Name="Column3"
Width="{ Binding ElementName=Column1, Path=Width }"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="Green"/>
<GridSplitter Grid.Column="0" Width="5" />
<Label Grid.Column="1" Background="Yellow" />
<Label Grid.Column="2" Background="Red" />
</Grid>
</Grid>
</Page>