7

我有两个ItemsControl并排出现的独立 s。ItemsControls 绑定到相同的,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

4 回答 4

5

跟进Jobi Joy 的回答

您不能OneWayToSource在 Xaml 中为 ReadOnly 依赖属性 ActualHeight 执行直接绑定,但有许多解决方法。Kent Boogaart这个问题上的回答是我最喜欢的。所做的是它使用一个附加行为来侦听SizeChanged任何事件FrameworkElement并相应地更新两个附加属性,宽度和高度。

TextBlock例如,ActualHeight可以用来推入 ViewModel 的 Height 属性,例如

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

同步两个 ScrollViewers
您可以使用 aDependencyPropertyDescriptor来监听属性的变化,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);
}

实际尺寸行为

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-22T13:30:12.123 回答
0

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

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

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

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

于 2011-02-21T01:26:47.603 回答
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)"/>
于 2014-12-23T17:39:59.107 回答
0

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

ActualHeight使用它,我能够将每ListViewItem一个的只读绑定ListView到我的项目视图模型中名为ListViewItemHeight. 然后,在第二个ListView中,我将每个项目的高度绑定到ListViewItemHeight.

于 2020-11-16T21:56:39.757 回答