Pregunta

Tengo dos separados ItemsControls que aparecen al lado.El ItemsControls se unen a la misma ItemsSource, pero que muestran los datos de manera diferente.

Cada elemento que aparece en la izquierda más probable es que sea más pequeño que el mismo artículo en el derecho.Esto provoca un problema debido a que las filas no se alinean, así que necesito el elemento de la izquierda para enlazar con el elemento de la derecha.

ItemsControl        ItemsControl
|Item 1         |Item 1
|Item 2         |Item 2
|Item 3         |
|Item 4         |Item 3

Como se puede ver, el Punto 2 de la derecha es más grande, por lo que se produce fuera de la alineación.Así que si me puede obligar a la izquierda del Punto 2 a la derecha del Punto 2 del ActualHeight el problema estaría resuelto.¿Cómo puedo hacer esto en XAML?

Editar: Para hacer las cosas más complicadas, el ItemsControl en la derecha necesita para desplazarse de derecha a izquierda, pero ambos ItemsControls necesidad de desplazarse arriba y abajo juntos.Básicamente, el de la izquierda proporciona un encabezado de tipo de los elementos a la derecha.

¿Fue útil?

Solución

El seguimiento de los Trabajoi de Alegría respuesta

Usted no puede hacer un directo OneWayToSource Enlace en el código Xaml de la Propiedad de Dependencia de sólo lectura de la ActualHeight pero hay muchas soluciones.La respuesta por Kent Boogaart en esta pregunta es mi favorito.Lo que se hace es que se utiliza, se Adjunta un Comportamiento que escucha a la SizeChanged evento de cualquier FrameworkElement y las actualizaciones de dos de las Propiedades Adjuntas, la Anchura y la Altura, respectivamente.

Con un TextBlock por ejemplo, ActualHeight puede ser utilizado para empujar a una Altura de propiedad de la Perspective como

<TextBlock local:ActualSizeBehavior.ObserveActualSize="True"
           local:ActualSizeBehavior.ActualHeight="{Binding Path=Height,
                                                           Mode=OneWayToSource}"
           .../>

Synkronize dos ScrollViewers
También se puede usar un DependencyPropertyDescriptor para escuchar los cambios en la VerticalOffsetProperty propiedad o suscribirse a la ScrollChanged evento y llamar ScrollToVerticalOffset.Ejemplo

Xaml

<ScrollViewer Name="scrollViewerLeft"
              ScrollChanged="scrollViewerLeft_ScrollChanged">
<ScrollViewer Name="scrollViewerRight"
              ScrollChanged="scrollViewerRight_ScrollChanged">

Código detrás de los controladores de eventos

private void scrollViewerLeft_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
    scrollViewerRight.ScrollToVerticalOffset(scrollViewerLeft.VerticalOffset);
}
private void scrollViewerRight_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
    scrollViewerLeft.ScrollToVerticalOffset(scrollViewerRight.VerticalOffset);
}

ActualSizeBehavior

public static class ActualSizeBehavior
{
    public static readonly DependencyProperty ActualSizeProperty =
        DependencyProperty.RegisterAttached("ActualSize",
                                            typeof(bool),
                                            typeof(ActualSizeBehavior),
                                            new UIPropertyMetadata(false, OnActualSizeChanged));
    public static bool GetActualSize(DependencyObject obj)
    {
        return (bool)obj.GetValue(ActualSizeProperty);
    }
    public static void SetActualSize(DependencyObject obj, bool value)
    {
        obj.SetValue(ActualSizeProperty, value);
    }
    private static void OnActualSizeChanged(DependencyObject dpo,
                                            DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = dpo as FrameworkElement;
        if ((bool)e.NewValue == true)
        {
            element.SizeChanged += element_SizeChanged;
        }
        else
        {
            element.SizeChanged -= element_SizeChanged;
        }
    }

    static void element_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        FrameworkElement element = sender as FrameworkElement;
        SetActualWidth(element, element.ActualWidth);
        SetActualHeight(element, element.ActualHeight);
    }

    private static readonly DependencyProperty ActualWidthProperty =
        DependencyProperty.RegisterAttached("ActualWidth", typeof(double), typeof(ActualSizeBehavior));
    public static void SetActualWidth(DependencyObject element, double value)
    {
        element.SetValue(ActualWidthProperty, value);
    }
    public static double GetActualWidth(DependencyObject element)
    {
        return (double)element.GetValue(ActualWidthProperty);
    }

    private static readonly DependencyProperty ActualHeightProperty =
        DependencyProperty.RegisterAttached("ActualHeight", typeof(double), typeof(ActualSizeBehavior));
    public static void SetActualHeight(DependencyObject element, double value)
    {
        element.SetValue(ActualHeightProperty, value);
    }
    public static double GetActualHeight(DependencyObject element)
    {
        return (double)element.GetValue(ActualHeightProperty);
    }
}

Otros consejos

Desde el ItemsSource es igual en ambos, usted puede usar una sola ItemsControl y toda una fila representado como dos secciones (Dos columnas de una Cuadrícula) en el interior que solo DataTemplate, entonces heights se alinean automáticamente.Siempre se puede dar el estilo para que parezca que es parte de dos diferentes ItemsControl pero, técnicamente, uno.

Otra manera de ir con esto es, la adición de una Altura de propiedad en el ViewModel (supuesto, no es muy correcto diseño, ya que la adición de Vista de la dependencia de la VM).TwoWay obligar a la altura de la ActualHeight de la izquierda-itemsControl ItemContainerStyle.Y a la derecha-itemscontrol se unen a la Altura de la propiedad a la Altura de ItemsContainerStyle {Una Manera}.Por lo tanto será en la sincronización.

Otra idea basada en su actualización de la Necesidad de desplazamiento en el lado derecho' :El uso de un ListView único y tiene dos columnas, y de los dos GridViewColumn.CellTemplate tener dos DataTemplates.Esta es la idea que sigue necesidades de la columna de la congelación en la primera columna.Pero que puede ser más complicado.

De todos modos me gustaría ir con el primer enfoque aquí.

Echa un vistazo a mi artículo: http://www.codeproject.com/KB/WPF/BindingHub.aspx

Que trata de cómo se puede enlazar a la Dependencia de Sólo Lectura usando las Propiedades de BindingHub:

<bindings:BindingHub 
       Visibility="Hidden"
       Socket1="{Binding ActualWidth, ElementName=Item, Mode=OneWay}"
       Socket2="{Binding ItemWidth, Mode=OneWayToSource}"
       Connect="(1 in, 2 out)"/>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top