我有两个单独的ItemsControl,它们并排出现。ItemsControl的绑定到相同的ItemsSource,但它们显示数据的方式不同。
左边显示的每一项都很可能比右边的同一项小。这会导致问题,因为行将不对齐,所以我需要左边的项来绑定到右侧的项。
ItemsControl ItemsControl
|Item 1 |Item 1
|Item 2 |Item 2
|Item 3 |
|Item 4 |Item 3正如您所看到的,右边的第2项更大,因此它抛出了对齐。所以,如果我能把左边的第二项绑定到右边的第二项的ActualHeight上,问题就解决了。我如何在XAML中做到这一点?
编辑:为了使事情变得更复杂,右边的ItemsControl需要向左滚动,但是两个ItemsControls都需要向上和向下滚动。基本上,左边的标题为右边的项提供了一个排序的标题。
发布于 2011-02-22 13:30:12
继续跟进Joy的回答
您不能在Xaml中为ReadOnly依赖项属性ActualHeight执行直接的ActualHeight绑定,但是有很多解决办法。肯特·布加特在this question中的回答是我最喜欢的。它所做的是使用一个附加行为,它侦听任何SizeChanged事件的FrameworkElement事件,并相应地更新两个附加属性,宽度和高度。
例如,使用TextBlock,可以使用ActualHeight推进到ViewModel的高度属性中,如
<TextBlock local:ActualSizeBehavior.ObserveActualSize="True"
local:ActualSizeBehavior.ActualHeight="{Binding Path=Height,
Mode=OneWayToSource}"
.../>同步两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);
}
}发布于 2011-02-21 01:26:47
因为两个ItemsSource都是相同的,所以可以在单个DataTemplate中使用单个ItemsControl和整个行表示为两个部分(网格的两个列),然后高度将自动对齐。您可以始终将其样式设置为看起来像是两种不同的ItemsControl的一部分,但技术上是一种。
另一种方法是在ViewModel中添加一个with属性(当然,由于向VM中添加了View依赖项,所以设计不太正确)。TwoWay将高度绑定到左侧itemsControl ItemContainerStyle的ActualHeight。在右项控件上,将该高度属性绑定到ItemsContainerStyle {单向}的高度。所以两者是同步的。
另一个基于更新‘需要右侧滚动’的想法:使用单个ListView并在其中包含两个列,而这两个GridViewColumn.CellTemplate中有两个DataTemplates。这个想法仍然需要在第一列上冻结列。但这可能更棘手。
无论如何,我会选择第一种方法。
发布于 2014-12-23 17:39:59
看看我的文章: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)"/>https://stackoverflow.com/questions/5061237
复制相似问题