绑定到Item ItemsControl的ActualHeight

时间:2011-02-21 00:39:26

标签: wpf xaml binding itemscontrol actualheight

我有两个独立的ItemsControl并排出现。 ItemsControl绑定到同一ItemsSource,但它们以不同方式显示数据。

左侧显示的每个项目很可能小于右侧的相同项目。这会导致问题,因为行不会排成一行,所以我需要左边的项目绑定到右边的项目。

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

如您所见,右侧的第2项较大,因此会抛弃对齐方式。因此,如果我可以将左边的第2项绑定到右边的第2项ActualHeight,问题就会解决。我怎么能在XAML中做到这一点?

修改:为了使事情变得更复杂,右侧的ItemsControl需要从右向左滚动,但ItemsControls都需要一起向上和向下滚动。基本上,左边的一个为右边的项目提供了各种标题。

4 个答案:

答案 0 :(得分:3)

跟进 Jobi Joy的回答

您无法在Xaml中为ReadOnly依赖项属性ActualHeight执行直接OneWayToSource绑定,但有许多解决方法。 Kent Boogaart this question中的回答是我最喜欢的。它的作用是使用附加行为来侦听任何SizeChanged的{​​{1}}事件,并相应地更新两个附加属性,宽度和高度。

FrameworkElement为例,TextBlock可用于推入ViewModel的Height属性,如

ActualHeight

Synkronize两个ScrollViewers
您可以使用<TextBlock local:ActualSizeBehavior.ObserveActualSize="True" local:ActualSizeBehavior.ActualHeight="{Binding Path=Height, Mode=OneWayToSource}" .../> 来监听DependencyPropertyDescriptor媒体资源中的更改,也可以订阅VerticalOffsetProperty事件并致电ScrollChanged。实施例

<强>的Xaml

ScrollToVerticalOffset

事件处理程序背后的代码

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

<强> ActualSizeBehavior

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

答案 1 :(得分:0)

由于ItemsSource在两者上都相同,因此您可以在单个ItemsControl内使用单个DataTemplate和整行表示为两个部分(网格的两列),然后高度将自动对齐。您总是可以将其设置为看起来像是两个不同的ItemsControl的一部分,但在技术上是一个。

另一种方法是,在ViewModel中添加一个Height属性(当然不是非常正确的设计,因为将View依赖项添加到VM )。 TwoWay将高度绑定到left-itemsControl ItemContainerStyle的ActualHeight。在right-itemscontrol上将Height属性绑定到ItemsContainerStyle {One Way}的高度。所以两者都会同步。

根据您的更新“右侧需要滚动”的另一个想法:    使用单个ListView并在其中包含两列,其中两个GridViewColumn.CellTemplate包含两个DataTemplates。这个想法仍然需要第一列的列冻结。但这可能会更棘手。

无论如何,我会采用第一种方法。

答案 2 :(得分:0)

看一下我的文章: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)"/>

答案 3 :(得分:0)

我必须解决这个确切的问题。我使用了在这里找到的只读绑定解决方案: https://meleak.wordpress.com/2011/08/28/onewaytosource-binding-for-readonly-dependency-property/

使用此方法,我可以将一个ActualHeight中每个ListViewItem的只读ListView绑定到项目视图模型中一个名为ListViewItemHeight的属性。然后,在第二个ListView中,我将每个项目的高度都绑定到ListViewItemHeight