防止 WPF 控件扩展到可见区域之外

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4521508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:25:35  来源:igfitidea点击:

Prevent WPF control from expanding beyond viewable area

wpfxaml

提问by Dan dot net

I have an ItemsControlin my user control with a scroll viewer around it for when it gets too big (Too big being content is larger than the viewable area of the UserControl). The problem is that the grid that it is all in just keeps expanding so that the scroll viewer never kicks in (unless I specify an exact height for the grid). See code below and thanks in advance.

我的ItemsControl用户控件中有一个滚动查看器,当它变得太大时(太大是内容大于 的可视区域UserControl)。问题是它所在的网格一直在扩展,因此滚动查看器永远不会启动(除非我为网格指定了确切的高度)。请参阅下面的代码并提前致谢。

 <UserControl  x:Class="BusinessObjectCreationWizard.View.TableSelectionPageView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <GroupBox FontWeight="Bold" Height="300px"
              Header="Tables"
              Padding="2">

        <ScrollViewer>

            <ItemsControl FontWeight="Normal" 
                          ItemsSource="{Binding Path=AvailableTables}">
                <ItemsControl.ItemTemplate>

                    <DataTemplate>              
                        <CheckBox Content="{Binding Path=DisplayName}"
                                  IsChecked="{Binding Path=IsSelected}"
                                  Margin="2,3.5" /> 
                    </DataTemplate> 
                </ItemsControl.ItemTemplate> 
            </ItemsControl>
        </ScrollViewer>
    </GroupBox>
</UserControl>

This user control is loaded here

此用户控件在此处加载

<Border Background="White" Grid.Column="1" Grid.Row="0">
        <HeaderedContentControl Content="{Binding Path=CurrentPage}" 
                                Header="{Binding Path=CurrentPage.DisplayName}" />
</Border>

I would like to not specify the height.

我不想指定高度。

回答by Joe White

If you remove the Height from your GroupBox (which, as far as I understand, is what you want to do), then it will fill its container, unless there's a panel upstream that imposes its own sizing rules.

如果您从 GroupBox 中删除 Height (据我所知,这是您想要做的),那么它将填充其容器,除非上游有一个面板施加其自己的大小规则。

I used this simplified version of your XAML. I removed the template and the binding, and hard-coded some items, to make this stand alone; those changes won't affect the way layout is done.

我使用了您的 XAML 的这个简化版本。我删除了模板和绑定,并对一些项目进行了硬编码,使其独立;这些更改不会影响布局的完成方式。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <GroupBox FontWeight="Bold" Header="Tables" Padding="2">
        <ScrollViewer>
            <ItemsControl FontWeight="Normal">
                <TextBlock>Foo</TextBlock>
                <TextBlock>Bar</TextBlock>
                <TextBlock>Baz</TextBlock>
            </ItemsControl>
        </ScrollViewer>
    </GroupBox>
</Window>

Run it, and you'll see that the content does indeed size to fit the window, and the scrollbar only enables when the window gets too small to see all three items. I believe this is what you want.

运行它,您将看到内容的大小确实适合窗口,并且滚动条仅在窗口太小而无法看到所有三个项目时启用。我相信这就是你想要的。

So the problem is most likely one of the parent panels, one you're not showing in your sample XAML. The problem you describe could occur if your GroupBox appears inside a StackPanel:

所以问题很可能是父面板之一,您没有在示例 XAML 中显示。如果您的 GroupBox 出现在 StackPanel 中,则可能会出现您描述的问题:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <StackPanel>
        <GroupBox FontWeight="Bold" Header="Tables" Padding="2">
            <ScrollViewer>
                <ItemsControl FontWeight="Normal">
                    <TextBlock>Foo</TextBlock>
                    <TextBlock>Bar</TextBlock>
                    <TextBlock>Baz</TextBlock>
                </ItemsControl>
            </ScrollViewer>
        </GroupBox>
    </StackPanel>
</Window>

Now the GroupBox appears at the top of the Window, sized to exactly fit its contents. If you shrink the Window enough, the GroupBox will be cut off -- because it's sized to fit its content, not its container. This sounds like the problem you're describing.

现在 GroupBox 出现在窗口的顶部,大小正好适合其内容。如果您足够缩小 Window,GroupBox 将被切断——因为它的大小适合其内容,而不是其容器。这听起来像你描述的问题。

The reason is that StackPanel asks its children what their ideal height is (based on their content), and uses that height. Without StackPanel (or something similar), the default is to respect the control's VerticalAlignment, and if that's set to the default value of Stretch, then the control is stretched to fill its parent. This means it won't be taller than its parent, which sounds like what you want.

原因是 StackPanel 询问它的孩子他们的理想高度是多少(基于他们的内容),并使用该高度。如果没有 StackPanel(或类似的东西),默认值是尊重控件的 VerticalAlignment,如果设置为 Stretch 的默认值,则控件被拉伸以填充其父级。这意味着它不会比它的父母高,这听起来像你想要的。

Solution: remove the StackPanel (or whatever else is causing you problems) and use something else. Depending on what you're trying to accomplish, you might have better luck with a DockPanel or a Grid. Hard to tell without knowing more about your layout.

解决方案:删除 StackPanel(或其他任何导致您出现问题的东西)并使用其他东西。根据您要完成的任务,使用 DockPanel 或 Grid 可能会更好。如果不了解更多有关您的布局的信息,就很难说。

Edit:Okay, it looks like the problem is indeed the HeaderedContentControlparent -- but not directly. HeaderedContentControl isn't a panel, so it doesn't do any layout of its own (and its descendant, GroupBox, doesn't have this same problem). The problem is its default template -- which includes a StackPanel. The good news is, you're free to use a different template, let's say one with a DockPanel instead:

编辑:好的,看起来问题确实出在HeaderedContentControl父母身上——但不是直接的。HeaderedContentControl 不是面板,所以它不做任何自己的布局(它的后代 GroupBox 没有同样的问题)。问题在于它的默认模板——其中包括一个 StackPanel。好消息是,您可以自由使用不同的模板,让我们说一个带有 DockPanel 的模板:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <HeaderedContentControl>
    <HeaderedContentControl.Style>
      <Style TargetType="{x:Type HeaderedContentControl}">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type HeaderedContentControl}">
              <DockPanel>
                <ContentPresenter ContentSource="Header" DockPanel.Dock="Top"/>
                <ContentPresenter/>
              </DockPanel>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </HeaderedContentControl.Style>
    <GroupBox FontWeight="Bold" Header="Tables" Padding="2">
      <ScrollViewer>
        <ItemsControl FontWeight="Normal">
          <TextBlock>Foo</TextBlock>
          <TextBlock>Bar</TextBlock>
          <TextBlock>Baz</TextBlock>
        </ItemsControl>
      </ScrollViewer>
    </GroupBox>
  </HeaderedContentControl>
</Window>

If you leave off the <HeaderedContentControl.Style>part, this reproduces your problem; but with the style in place, it allows the GroupBox to fill its container, so the ScrollViewer will get a scrollbar when you want it to.

如果你离开这个<HeaderedContentControl.Style>部分,这会重现你的问题;但是有了适当的样式,它允许 GroupBox 填充其容器,因此 ScrollViewer 将在您需要时获得滚动条。

回答by softwarequestioneer

If the previous answer doesn't fix the problem, you could also try binding the Width, Height of your grid to the ActualWidth, ActualHeight of your parent UserControl. Something like:

如果上一个答案没有解决问题,您还可以尝试将网格的宽度、高度绑定到父 UserControl 的 ActualWidth、ActualHeight。就像是:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication.UserControl1"
x:Name="UserControl">
<Grid Height="{Binding ElementName=UserControl, Path=ActualHeight}"
      Width="{Binding ElementName=UserControl, Path=ActualWidth}" />

In this case you aren't setting an explicit width and height but you are limiting the Grids width/height to the constraints of the UserControl it sits in.

在这种情况下,您没有设置明确的宽度和高度,而是将网格宽度/高度限制为它所在的 UserControl 的约束。

回答by user5454778

I had the same issue, after reading this response I replaced all StackPanels with Grids in UserControl. It resolved the Scrollbar issue.

我遇到了同样的问题,在阅读此回复后,我将 UserControl 中的所有 StackPanels 替换为 Grids。它解决了滚动条问题。

回答by Clifford Nelson

They are different. If you do not want to have the items selectable, then don't use a ListBox. It is going to be heavier, and will also have the deselect a selection everytime the user clicks on an entry. Just put the ItemsControl in a ScrollViewer

它们是不同的。如果您不想让项目可选,则不要使用 ListBox。它会更重,并且每次用户单击条目时都会取消选择一个选择。只需将 ItemsControl 放在 ScrollViewer 中

回答by userJeff344

I had the same problema with ListBox, it wasn't expanding and the scroll viewer didn't appear. I solved it as follows:

我在 ListBox 上遇到了同样的问题,它没有扩展,也没有出现滚动查看器。我是这样解决的:

 <UserControl x:Class="TesteView" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <Grid MaxHeight="710">
      ....
      ....
      <StackPanel>
         <ListBox  MaxHeight="515" 
            ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
            ScrollViewer.VerticalScrollBarVisibility="Auto" 
            ItemsSource="{Binding Path=Teste,Mode=TwoWay}">
            ....
            ....
        </ListBox>
     </StackPanel>
    </Grid>
   </UserControl>

回答by odyth

Why not just use a listbox instead of an itemscontrol, that has a built in scrollviewer.

为什么不使用列表框而不是具有内置滚动查看器的项目控件。

回答by Dan Puzey

Try removing the grid entirely and setting the HorizontalAlignment and VerticalAlignment directly on the GroupBox. If a layoutpanel has only one child, it's often redundant... this migth be true in your case.

尝试完全删除网格并直接在 GroupBox 上设置 Horizo​​ntalAlignment 和 VerticalAlignment。如果布局面板只有一个子项,则通常是多余的……这在您的情况下可能是正确的。

If that doesn't work... what's the parent of your grid control?

如果这不起作用......你的网格控件的父级是什么?