【问题标题】:Problem with custom scrolling in custom panel自定义面板中的自定义滚动问题
【发布时间】:2010-10-20 14:18:20
【问题描述】:

我正在编写一个表示手牌的自定义面板。这是一个将卡片水平堆叠的面板。如果没有足够的空间,每张卡片将与左边卡片的一部分重叠。最小部分应始终可见。我完成了这个,这是代码:

using System;
using System.Windows;
using System.Windows.Controls;

namespace Hand
{
   public class Hand : Panel
   {
      //TODO Should be dependancy property
      private const double MIN_PART = 0.5;

      protected override Size MeasureOverride(Size availableSize)
      {
         Size desiredSize = new Size();
         foreach (UIElement element in this.Children)
         {
            element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

            desiredSize.Width += element.DesiredSize.Width;
            desiredSize.Height = Math.Max(desiredSize.Height, element.DesiredSize.Height);
         }
         return desiredSize;
      }

      protected override Size ArrangeOverride(Size finalSize)
      {
         //percentage of the visible part of the child.
         double part = 1;

         Double desiredWidth = 0;

         //TODO Check how to get desired size because without looping
         //this.DesiredSize is minimum of available size and size returned from MeasureOverride
         foreach (UIElement element in this.Children)
         {
            desiredWidth += element.DesiredSize.Width;
         }

         if (desiredWidth > this.DesiredSize.Width)
         {
            //Every, but the last child should be overlapped
            double lastChildWidth = this.Children[this.Children.Count - 1].DesiredSize.Width;
            part = (this.DesiredSize.Width - lastChildWidth) / (desiredWidth - lastChildWidth);

            part = Math.Max(part, MIN_PART);
         }

         double x = 0;

         foreach (UIElement element in this.Children)
         {
            Rect rect = new Rect(x, 0, element.DesiredSize.Width, element.DesiredSize.Height);
            element.Arrange(rect);
            finalSize.Width = x + element.DesiredSize.Width;
            x += element.DesiredSize.Width * part;
         }

         return finalSize;
      }
   }
}

我想在达到最小部分时添加滚动条,以便用户仍然可以查看所有卡片。我无法做到这一点。我尝试使用这样的 ScrollViewer:

<Window x:Class="TestScrollPanel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:h="clr-namespace:Hand;assembly=Hand"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto">
        <h:Hand>
            <Button Width="100">One</Button>
            <Button Width="150">Two</Button>
            <Button Width="200">Three</Button>
        </h:Hand>
        </ScrollViewer>
    </Grid>
</Window>

但这不起作用,因为一旦水平滚动条可见,Hand 面板的 MeasureOveride 和 ArrangeOverride 就不会被调用,即使会被调用,Hand 也会获得所需的大小来排列所有子项而不重叠。

这完全可以用 ScrollViewer 制作吗?如果没有,我们将不胜感激。 谢谢大家的帮助。

朱莉卡

【问题讨论】:

    标签: wpf scrollviewer custom-panel


    【解决方案1】:

    首先,将面板的逻辑改为相反:让MeasureOverride 将卡片包装得尽可能紧密,然后让ArrangeOverride 将它们均匀地分布在给定的任何宽度上。

    其次,使用MinWidth 属性。绑定到ScrollViewer.ActualWidth

    这样,如果卡片可以紧密地包装成小于ScrollViewer 的宽度,那么您的Hand 将被拉伸到所有可用空间。如果他们不能,那么Hand 的宽度就是你计算出来的任何值。

    【讨论】:

    • 非常感谢。这是我一直在寻找的答案。非常整洁。我相信绑定不是必需的,因为没有它它也可以工作。
    猜你喜欢
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 2012-03-02
    相关资源
    最近更新 更多