WPF画布面板和滚动 [英] WPF wrap panel and scrolling

查看:134
本文介绍了WPF画布面板和滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 WrapPanel ,其中包含了许多广泛的控制。当我调整窗口的宽度 一切正常。如果有足够的空间的控制会横跨在一行或包裹到​​下一行的时候没有。



不过,我需要发生的是如果所有的控件基本上是垂直堆叠(因为没有更多的横向空间)和窗口宽度 >更是下降,水平滚动条出现,这样我可以滚动,并看到整个的控制,如果我想。下面是我的XAML。我试着包裹 WrapPanel 的ScrollViewer ,但我无法实现我的目标。

 <窗​​口x:类=WpfQuotes.Window1
的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/ XAML /演示
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
标题=窗口1HEIGHT =自动WIDTH =600前景= 白>
< WrapPanel>
<按钮WIDTH =250> 1 LT; /按钮>
将按钮宽度=250→2&下; /按钮>
<按钮WIDTH =250> 3',/按钮>
< / WrapPanel>
< /窗GT;



所以,如果你减少的宽度的上述窗口到最小,你将无法看到按钮的文本。我想一个水平滚动条出现,这样我可以滚动查看的文本,但不与通常的包装功能造成干扰。



感谢。



更新:
我都遵循以下保罗的建议和水平滚动条像现在出现预期。不过,我也想垂直滚动可用,因此我设置 VerticalScrollBarVisibility =自动。问题是,如果我调整窗口的大小,这样会出现一个垂直滚动条,水平人们也总是出现,即使不需要它(有足够的水平空间看到整个控制)。这似乎是出现与ScrollViewer中的宽度搞乱垂直滚动条。是否有办法来纠正这一点,以便水平滚动条不会出现,除非它实际需要?



下面是我的XAML和我在添加的唯一代码 CustomWrapPanel

 <窗​​口x:类=窗口1
的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/presentation
的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
的xmlns:CWP =CLR的命名空间:CustomWrapPanelExample
标题=窗口1HEIGHT =自动WIDTH =300前景=白NAME =mainPanel中>
<的ScrollViewer X:NAME =MyScrollViewerHorizo​​ntalScrollBarVisibility =自动
VerticalScrollBarVisibility =自动>
< CWP:CustomWrapPanel WIDTH ={绑定的ElementName = MyScrollViewer,路径= ActualWidth的}>
<按钮WIDTH =250> 1 LT; /按钮>
将按钮宽度=250→2&下; /按钮>
<按钮WIDTH =250> 3',/按钮>
<按钮WIDTH =250> 4℃; /按钮>
<按钮WIDTH =250> 5℃/按钮>
<按钮WIDTH =250> 6≤/按钮>
<按钮WIDTH =250> 7 LT; /按钮>
<按钮WIDTH =250> 8示/按钮>
<按钮WIDTH =250> 9< /按钮>
< / CWP:CustomWrapPanel>
< /&的ScrollViewer GT;
< /窗GT;

CustomWrapPanel 覆盖的唯一的事:

 保护覆盖面积的MeasureOverride(尺寸availableSize)
{
双maxChildWidth = 0;
如果(Children.Count大于0)
{
的foreach(EL的UIElement儿童)
{
如果(el.DesiredSize.Width> maxChildWidth)
{
maxChildWidth = el.DesiredSize.Width;
}
}
}
=了minWidth maxChildWidth;
返回base.MeasureOverride(availableSize);
}


解决方案

这里的东西,如果你的将使用一个缠绕面板,它有两个作用,它会占用尽可能多的可用空间的一个方向,并根据需要在其他扩展。举例来说,如果你将它放在一个窗口里面像你拥有了它,它需要尽可能多的水平空间,因为它可以,然后根据向下需要扩展,这就是为什么一个垂直滚动条会的工作,父容器说:这是我有多宽是,但你可以让自己一样大,你想要垂直,如果你将其更改为水平滚动条,滚动浏览器基本上等于在说:这是你能有多高可以,但你可以作为宽要,在这种情况下,包面板不换行,因为没有横向约束



一种可能的解决方案是改变画布面板从横换到的方向纵是这样的(这可能不是理想或预期的行为):

 <的ScrollViewer Horizo​​ntalScrollBarVisibility =自动VerticalScrollBarVisibility =禁用> 
< WrapPanel方向=垂直>
<按钮WIDTH =250> 1 LT; /按钮>
将按钮宽度=250→2&下; /按钮>
<按钮WIDTH =250> 3',/按钮>
< / WrapPanel>
< /&的ScrollViewer GT;

为了让你的期望的行为,你必须做一些事情更接近这一点:

 <的ScrollViewer X:NAME =MyScrollViewerHorizo​​ntalScrollBarVisibility =自动VerticalScrollBarVisibility =已禁用> 
< WrapPanel了minWidth =250WIDTH ={绑定的ElementName = MyScrollViewer,路径= ViewportWidth}>
<按钮WIDTH =250> 1 LT; /按钮>
将按钮宽度=250→2&下; /按钮>
<按钮WIDTH =250> 3',/按钮>
< / WrapPanel>
< /&的ScrollViewer GT;



然而,这第二个解决方案仅适用,如果你已经知道你的孩子元素的宽度,理想情况下你想你的最大宽度设置为最大的子项的实际宽度,但为了做到这一点你必须创建一个从画布面板派生的自定义控制和编写代码自己来检查这一点。


I have a simple WrapPanel which contains a number of wide controls. When I resize the Width of the Window everything works as expected. The controls will go across on a single line if there is enough space or wrap down to the next line when there isn't.

However, what I need to happen is that if all of the controls are basically stacked vertically (since there is no more horizontal space) and the Width of the Window is decreased even more, a horizontal scroll bar appears so that I can scroll and see the entire control if I want to. Below is my xaml. I tried wrapping the WrapPanel in a ScrollViewer but I couldn't achieve my goal.

<Window x:Class="WpfQuotes.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="Auto" Width="600" Foreground="White">
    <WrapPanel>
      <Button Width="250">1</Button>
      <Button Width="250">2</Button>
      <Button Width="250">3</Button>
    </WrapPanel>
</Window>

So if you reduce the Width of the above Window to its minimum, you will not be able to see the text of the buttons. I would like a horizontal scroll bar appear so that I can scroll to see the text but not interfere with the usual wrapping functionality.

Thanks.

Update: I have followed Paul's suggestion below and the horizontal scrollbar appears as expected now. However, I also wanted vertical scrolling available so I set VerticalScrollBarVisibility="Auto". The thing is, if I resize the window so that a vertical scroll bar appears, the horizontal one also always appears, even if it is not needed (there is enough horizontal space to see the entire control). It seems like the vertical scrollbar appearing is messing with the width of the scrollviewer. Is there a way to correct this so that the horizontal scrollbar doesn't appear unless it is actually needed?

Below is my xaml and the only code I added in the CustomWrapPanel:

<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cwp="clr-namespace:CustomWrapPanelExample"
        Title="Window1" Height="Auto" Width="300" Foreground="White" Name="mainPanel">
  <ScrollViewer x:Name="MyScrollViewer" HorizontalScrollBarVisibility="Auto"
                VerticalScrollBarVisibility="Auto">
    <cwp:CustomWrapPanel Width="{Binding ElementName=MyScrollViewer, Path=ActualWidth}">
      <Button Width="250">1</Button>
      <Button Width="250">2</Button>
      <Button Width="250">3</Button>
      <Button Width="250">4</Button>
      <Button Width="250">5</Button>
      <Button Width="250">6</Button>
      <Button Width="250">7</Button>
      <Button Width="250">8</Button>
      <Button Width="250">9</Button>
    </cwp:CustomWrapPanel>
  </ScrollViewer>
</Window>

The only thing overridden in CustomWrapPanel:

protected override Size MeasureOverride(Size availableSize)
{
  double maxChildWidth = 0;
  if (Children.Count > 0)
  {
    foreach (UIElement el in Children)
    {
      if (el.DesiredSize.Width > maxChildWidth)
      {
        maxChildWidth = el.DesiredSize.Width;
      }
    }
  }      
  MinWidth = maxChildWidth;
  return base.MeasureOverride(availableSize);
}

解决方案

Here's the thing, if your going to use a wrap panel, it does two things, it will take up as much available space in one direction, and expand as needed in the other. For instance, if you place it inside of a window like you have it, it takes up as much horizontal space as it can, and then expands as needed downward, that's why a vertical scroll bar will work, the parent container says "this is how wide I am, but you can make yourself as big as you want vertically", if you change it to a horizontal scroll bar, the scroll viewer is essentially saying "this is how tall you can be, but you can be as wide as you want" in this case the wrap panel doesn't wrap because there is no horizontal constraints.

One potential solution is to change the direction the wrap panel wraps from horizontal to vertical like this (Which is probably not the ideal or expected behavior):

    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
        <WrapPanel Orientation="Vertical">
            <Button Width="250">1</Button>
            <Button Width="250">2</Button>
            <Button Width="250">3</Button>
        </WrapPanel>
    </ScrollViewer>

In order to get the behavior your expecting, you'll have to do something closer to this:

    <ScrollViewer x:Name="MyScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
        <WrapPanel MinWidth="250" Width="{Binding ElementName=MyScrollViewer, Path=ViewportWidth}">
            <Button Width="250">1</Button>
            <Button Width="250">2</Button>
            <Button Width="250">3</Button>
        </WrapPanel>
    </ScrollViewer>

However, this second solution only works if you already know the width of your child elements, ideally you want your max width to be set to the actual width of the largest child item, but in order to do that you'd have to create a custom control that derives from wrap panel and write the code yourself to check for that.

这篇关于WPF画布面板和滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆