¿Cómo vinculo datos del ancho de una definición de columna o el alto de una definición de fila?

Resuelto Nidonocu asked hace 16 años • 4 respuestas

Bajo el patrón View-Model-ViewModel para WPF, estoy intentando vincular datos de alturas y anchos de varias definiciones para controles de cuadrícula, de modo que pueda almacenar los valores que el usuario establece después de usar un GridSplitter. Sin embargo, el patrón normal no parece funcionar para estas propiedades particulares.

Nota: Estoy publicando esto como una pregunta de referencia que estoy publicando porque Google me falló y tuve que resolverlo yo mismo. Mi propia respuesta a seguir.

Nidonocu avatar Sep 29 '08 15:09 Nidonocu
Aceptado

Cree un IValueConverterde la siguiente manera:

public class GridLengthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double val = (double)value;
        GridLength gridLength = new GridLength(val);

        return gridLength;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        GridLength val = (GridLength)value;

        return val.Value;
    }
}

Luego puede utilizar el convertidor en su enlace:

<UserControl.Resources>
    <local:GridLengthConverter x:Key="gridLengthConverter" />
</UserControl.Resources>
...
<ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
                                  Mode=TwoWay,
                                  Converter={StaticResource gridLengthConverter}}" />
Greg Sansom avatar Sep 09 '2011 07:09 Greg Sansom

Descubrí una serie de trampas:

  1. Aunque puede parecer un doble en XAML, el valor real de la altura o el ancho de una *definición es una estructura 'GridLength'.
  2. Todas las propiedades de GridLength son de solo lectura, debe crear una nueva cada vez que la cambie.
  3. A diferencia de cualquier otra propiedad en WPF, Ancho y Alto no establecen su modo de enlace de datos predeterminado en 'TwoWay', debe configurarlo manualmente.

Por lo tanto, utilicé el siguiente código:

private GridLength myHorizontalInputRegionSize = new GridLength(0, GridUnitType.Auto)
public GridLength HorizontalInputRegionSize
{
    get
    {
        // If not yet set, get the starting value from the DataModel
        if (myHorizontalInputRegionSize.IsAuto)
            myHorizontalInputRegionSize = new GridLength(ConnectionTabDefaultUIOptions.HorizontalInputRegionSize, GridUnitType.Pixel);
        return myHorizontalInputRegionSize;
    }
    set
    {
        myHorizontalInputRegionSize = value;
        if (ConnectionTabDefaultUIOptions.HorizontalInputRegionSize != myHorizontalInputRegionSize.Value)
        {
            // Set the value in the DataModel
            ConnectionTabDefaultUIOptions.HorizontalInputRegionSize = value.Value;
        }
        OnPropertyChanged("HorizontalInputRegionSize");
    }
}

Y el XAML:

<Grid.RowDefinitions>
    <RowDefinition Height="*" MinHeight="100" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" />
</Grid.RowDefinitions>
Nidonocu avatar Sep 29 '2008 08:09 Nidonocu

La solución más sencilla es simplemente usar configuraciones de cadena para estas propiedades para que WPF las admita automáticamente usando GridLengthConverter sin ningún trabajo adicional.

JustinMichel avatar May 06 '2015 17:05 JustinMichel