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

问题描述 投票:23回答:7

我的用户控件中有一个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>

此处加载此用户控件

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

我想不指定高度。

wpf xaml
7个回答
28
投票

如果从GroupBox中移除Height(根据我的理解,这是你想要做的),那么它将填充其容器,除非上游的面板强加了自己的大小调整规则。

我使用了这个简化版的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>

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

因此问题很可能是父面板之一,您未在样本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>

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

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

解决方案:删除StackPanel(或其他任何导致您问题的内容)并使用其他内容。根据您要完成的任务,您可能会更好地使用DockPanel或Grid。在不了解您的布局的情况下很难分辨。

编辑:好的,看起来问题确实是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>

如果你放弃<HeaderedContentControl.Style>部分,这将再现你的问题;但是在风格到位的情况下,它允许GroupBox填充其容器,因此ScrollViewer将在您需要时获得滚动条。


10
投票

如果上一个答案无法解决问题,您还可以尝试将网格的宽度,高度绑定到父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}" />

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


3
投票

我有同样的问题,在阅读此回复后,我用UserControl中的网格替换了所有StackPanels。它解决了Scrollbar问题。


1
投票

它们是不同的。如果您不想选择项目,请不要使用ListBox。它会变得更重,并且每次用户点击一个条目时也会取消选择。只需将ItemsControl放入ScrollViewer即可


0
投票

尝试完全删除网格并直接在GroupBox上设置Horizo​​ntalAlignment和VerticalAlignment。如果一个layoutpanel只有一个孩子,那么它通常是多余的...这种情况在你的情况下是真实的。

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


0
投票

为什么不使用列表框而不是itemcontrol,它具有内置的scrollviewer。


0
投票

我有与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>
© www.soinside.com 2019 - 2024. All rights reserved.