绑定到Item ItemsControl的ActualHeight

我有两个独立的
ItemsControl
s并排出现。
ItemsControl
s绑定到相同的
ItemsSource
,但它们以不同的方式显示数据。 左侧显示的每个项目很可能小于右侧的相同项目。这会导致问题,因为行不会排成一行,因此我需要左侧的项目绑定到右侧的项目。
ItemsControl        ItemsControl
|Item 1         |Item 1
|Item 2         |Item 2
|Item 3         |
|Item 4         |Item 3
如您所见,右侧的第2项更大,因此它会抛弃对齐。因此,如果我可以将左边的项目2绑定到右边的项目2的
ActualHeight
,问题就会得到解决。我怎样才能在XAML中做到这一点? 编辑:为了使事情变得更复杂,右边的
ItemsControl
需要从右向左滚动,但两者都需要一起向上和向下滚动。基本上,左边的一个为右边的项目提供了各种标题。     
已邀请:
跟进Jobi Joy的回答 你不能在Xaml中为ReadOnly依赖属性ActualHeight直接进行
OneWayToSource
绑定,但是有很多解决方法。 Kent Boogaart在这个问题上的答案是我最喜欢的。它的作用是使用一个附加行为来侦听任何
FrameworkElement
SizeChanged
事件,并相应地更新两个附加属性,宽度和高度。 以
TextBlock
为例,
ActualHeight
可用于推入ViewModel的Height属性,如
<TextBlock local:ActualSizeBehavior.ObserveActualSize="True"
           local:ActualSizeBehavior.ActualHeight="{Binding Path=Height,
                                                           Mode=OneWayToSource}"
           .../>
Synkronize两个ScrollViewers 您可以使用
DependencyPropertyDescriptor
收听
VerticalOffsetProperty
财产的变化,也可以订阅
ScrollChanged
活动并致电
ScrollToVerticalOffset
。例 XAML
<ScrollViewer Name="scrollViewerLeft"
              ScrollChanged="scrollViewerLeft_ScrollChanged">
<ScrollViewer Name="scrollViewerRight"
              ScrollChanged="scrollViewerRight_ScrollChanged">
事件处理程序背后的代码
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);
    }
}
    
由于
ItemsSource
在两者上都是相同的,你可以在单个
DataTemplate
中使用单个
ItemsControl
和整行表示为两个部分(网格的两列),然后高度将自动对齐。您总是可以将它设计为看起来像是两个不同的part0ѭ但在技术上是一个的一部分。 另一种方法是,在ViewModel中添加一个Height属性(当然,自从向VM添加View依赖项后,设计不是很正确)。 TwoWay将高度绑定到left-itemsControl ItemContainerStyle的ActualHeight。在right-itemscontrol上将Height属性绑定到ItemsContainerStyle {One Way}的高度。所以两者都会同步。 基于您的更新“右侧需要滚动”的另一个想法:    使用单个ListView并在其中包含两列,其中两个GridViewColumn.CellTemplate包含两个DataTemplates。这个想法仍然需要第一列的列冻结。但这可能更棘手。 无论如何,我会采用第一种方法。     
看一下我的文章:http://www.codeproject.com/KB/WPF/BindingHub.aspx 这就是使用BindingHub绑定到只读依赖项属性的方法:
<bindings:BindingHub 
       Visibility="Hidden"
       Socket1="{Binding ActualWidth, ElementName=Item, Mode=OneWay}"
       Socket2="{Binding ItemWidth, Mode=OneWayToSource}"
       Connect="(1 in, 2 out)"/>
    

要回复问题请先登录注册