2008-09-29 8 views
28

Bajo el patrón View-Model-ViewModel para WPF, estoy tratando de vincular las Alturas y Anchos de varias definiciones para los controles de cuadrícula, así puedo 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.¿Cómo puedo enlazar datos entre el ancho de una definición de columna o el alto de definición de hilera?

Nota: Estoy publicando esto como una pregunta de referencia que estoy publicando, ya que Google me falló y tuve que resolverlo por mi cuenta. Mi propia respuesta a seguir.

Respuesta

17

Hubo una serie de trampas que descubrí:

  1. Aunque pueda parecer como una doble en XAML, el valor real de una altura de * Definición o ancho 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 todas las demás propiedades en WPF, ancho y alto no predeterminan su modo de enlace de datos a 'TwoWay', tiene que configurarlo manualmente.

Thusly, he utilizado 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> 
+9

GridLength es específico de WPF, por lo tanto, no pertenece a la capa de ViewModel. –

+2

Creo que la creencia de "no WPF en ViewModel" es incorrecta, ya que WPF tiene muchas construcciones con respecto al patrón MVVM, como la propia unión de datos. En su lugar, podría decirse que "GridLength es específico de VIEW" (a menos que sea parte del problema del dominio, como en las aplicaciones de visualización de datos cuyo objetivo principal es el diseño y la visualización de cosas). Pero seguro que es controvertido ... – heltonbiker

+0

@heltonbiker "GridLength es específico de la VISTA" es más preciso. a menos que su lógica comercial sea única o parcialmente sobre el diseño de la interfaz de usuario (diseño) –

4

Otra posibilidad, ya que trajo hasta la conversión entre GridLength y int, es crear un IValueConverter y úsela cuando se vincula al Width. IValueConverter s también manejan enlaces bidireccionales porque tienen los métodos ConvertTo() y ConvertBack().

34

Crear una IValueConverter de 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; 
    } 
} 

Usted puede utilizar entonces el convertidor en su Encuadernación:

<UserControl.Resources> 
    <local:GridLengthConverter x:Key="gridLengthConverter" /> 
</UserControl.Resources> 
... 
<ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
            Mode=TwoWay, 
            Converter={StaticResource gridLengthConverter}}" /> 
+0

Si busca una solución a un problema muy similar, puede encontrarlo aquí: http://stackoverflow.com/questions/7660967/wpf-error-cannot -find-govering-frameworkelement-for-target-element – dzendras

+0

Wpf ya tiene una clase GridLengthConverter. ¿Sería posible usarlo tal cual? – heltonbiker

+4

@heltonbiker Desafortunadamente, GridLengthConverter implementa ITypeConverter en lugar de IValueConverter, por lo que no se puede usar como una conversión de enlace WPF. –

2

La solución más sencilla es utilizar simplemente la configuración de cadena para estas propiedades para que WPF los admite automáticamente usando GridLengthConverter sin ningún trabajo adicional.

Cuestiones relacionadas