如何使WPF中的控件自动调整大小,类似于Windows Form中的锚定/停靠属性?

30

我已经阅读了很多关于这个问题的解决方案,但每一个都无法解决我的问题。无论我把控件放到哪个容器中,或者在控件/容器上设置什么属性,它都不会改变大小。 我有一个带有控件的滚动视图。我希望它能够在用户在运行时调整窗口大小时与窗口一起调整大小。我只需要使用anchor=top, bottom, left, right。我不明白为什么在WPF中这么难以实现,为什么需要涉及容器对象和各种属性分配才能完成Windows Forms中一个属性就能完成的事情。但是针对这个问题的每一个解决方案仍然导致我的控件始终保持在其设计时的大小,当窗口在运行时调整大小时也不会改变。如何以简单的方式掌握WPF中的动态控件大小调整?


2
你能展示一下你现在所拥有的XAML代码吗? - svick
你可以尝试使用width/height = "*" 或者使用stackpanel。 - deathrace
5个回答

47

这也给我带来了烦恼,但AlexK帮助我看到了光明。诀窍在于不设置高度和宽度....将它们设置为AUTO并使用MARGIN设置尺寸。将HORIZONTALALIGNMENTVERTICALALIGNMENT设置为STRETCH,然后锚点功能就会起作用。


5
控件需要拉伸,这就是它的全部要求。
<MyControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>

Stretch代替了将锚点设置到两侧的方法。

有关面板的帮助,请参见此概述。还请查看布局系统的文档

大多数控件都会自动拉伸,如果您有一个DataGrid它也应该自动拉伸,这个示例包含一个DataGrid和一个TextBlock来显示其大小:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <DataGrid Name="grid">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
                <DataGridTextColumn Binding="{Binding Tag}" Header="Occupation"/>
            </DataGrid.Columns>
            <FrameworkElement Name="Skeet" Tag="Programmer"/>
            <FrameworkElement Name="Gravell" Tag="Programmer"/>
            <FrameworkElement Name="Steve" Tag="Coffee Getter"/>
        </DataGrid>
        <TextBlock Grid.Row="1">
            <TextBlock.Text>
                <MultiBinding StringFormat="{}{0}, {1}">
                    <Binding ElementName="grid" Path="ActualWidth"/>
                    <Binding ElementName="grid" Path="ActualHeight"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </Grid>
</Window>

如果您将窗口缩小,DataGrid的滚动条应该会出现。

我已尝试了所有可能的对齐设置,但控件始终保持在其设计时尺寸。肯定还有其他阻止其调整大小的因素存在,只是我看不到而已。 - Mike
控件所在的面板必须提供边界,否则它将无法伸展。滚动视图不会做到这一点,因为其整个目的是使查看任何大小的控件成为可能,通常不会限制其内容。编辑:实际上,在某些情况下,使用 ScrollViewer 也可以解决这个问题,这取决于所使用的控件。你现在使用的是什么控件? - H.B.
这是一个数据网格,我正在尝试使滚动查看器调整到窗口的大小(或可用的窗口大小,因为还有其他控件),但如果数据网格仍然太大,我希望滚动查看器能提供一种获取超出边界内容的方法。 - Mike
DataGrid拥有自己的ScrollViewer。 - H.B.

4

我假设不可调整大小的控件是您自定义的控件。

  • 使用DockPanel作为容器。
  • 从您的控件中删除显式的Width和Height属性。

如果您在VS2008中工作,则会造成不便,因为在设计器中查看时,您的控件将折叠到最小尺寸。

表达式混合和从VS2010开始均支持设计师命名空间,因此您可以指定仅在设计时控件大小。

为此,请将以下内容添加到您的控件中:

<UserControl ...
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d"
    d:DesignWidth="WWW" d:DesignHeight="HHH">
    ....
</UserControl>

d:DesignWidth和d:DesignHeight指定设计时的宽度和高度。


1
我尝试将它放在DockPanel中。在我看来,控件似乎会扩展以填充DockPanel,但是无论窗口变得多大,DockPanel本身的大小都保持不变。 - Mike
我不小心点了踩。当时我甚至没有意识到自己这么做了。我想撤销它,但是除非回答被编辑,否则我无法更改我的投票。 - TomDestry

1

这个问题很老了,但是既然我在这里找到了答案,我想我可以提供我的解决方案。下面的代码是一个带有两个选项卡的选项卡控件,每个选项卡都包含一个控件来填充选项卡。我删除了明确设置的宽度和高度,并将我想要调整大小的所有控件的水平和垂直对齐方式设置为自动。选项卡控件随着主窗口一起拉伸。选项卡中的控件会拉伸以填充选项卡。这些信息来自于这里的答案。我只是提供了一个完整的示例。

希望对某人有用。

        <TabControl HorizontalAlignment="Stretch" 
                Margin="91,0,0,0" Name="tabControl1"
                VerticalAlignment="Stretch" >
        <TabItem Header="DataGrid" Name="tabItem1">
            <Grid>
                <DataGrid AutoGenerateColumns="False" 
                          HorizontalAlignment="Stretch" 
                          Name="dgFTPLog"
                          VerticalAlignment="Stretch" 
                          Margin="6,6,0,0" />
            </Grid>
        </TabItem>
        <TabItem Header="Log" Name="tabItem2">
            <Grid>
                <TextBox 
                         HorizontalAlignment="Stretch" 
                         Margin="6,6,0,0" Name="txtLog"
                         VerticalAlignment="Stretch"
                         VerticalScrollBarVisibility="Auto" 
                         HorizontalScrollBarVisibility="Auto" 
                         TextChanged="txtLog_TextChanged" />
            </Grid>
        </TabItem>
    </TabControl>

-1
我也遇到了这个问题。尝试绑定到父控件的ActualHeight和ActualWidth属性,但只有在通过代码后台而不是XAML进行时才起作用。
例如: XAML
<MyParentControl x:name="parentControl" SizeChanged="parentControl_SizeChanged">
     <ChildControl x:name=childControl" />
</MyParentControl>

.cs的代码后台

private void parentControl_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        childControl.Height = parentControl.ActualHeight;
        childControl.Width = parentControl.ActualWidth;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接