当窗口最大化时,如何使所有控件按比例调整大小?

时间:2013-10-16 01:23:52

标签: wpf c#-4.0 mvvm

当我点击最大化按钮时,窗口最大化但控件没有按比例调整大小。使控件调整大小的最佳方法是什么?我正在使用MVVM。

这是我的代码。

<Window x:Class="DataTransfer.View.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Icon="/DataTransfer;component/View/Images/ms_msnexplore.gif"

        ResizeMode="CanResizeWithGrip"
        Title="Window1" Height="500" Width="600">
    <!--Style="{DynamicResource OfficeStyle}"-->
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!--<ResourceDictionary Source="/DataTransfer;component/View/WindowBase.xaml" />-->
                <!--<ResourceDictionary Source="/DataTransfer;component/Themes/WPFThemes/CalendarResource.xaml" />-->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width ="*" />
    </Grid.ColumnDefinitions>
        <Button Content="Button" HorizontalAlignment="Left" Margin="52,28,0,0" VerticalAlignment="Top" Width="75" Height="22" />
        <DatePicker Name="dp" HorizontalAlignment="Left" Margin="175,25,0,0" VerticalAlignment="Top" Width="123" Text="aaa" GotFocus="DateGotFocused" LostFocus="OnLeaveArchiveDate"/>
        <Calendar HorizontalAlignment="Left" Margin="47,162,0,0" VerticalAlignment="Top"/>
        <TextBox Name="t1" HorizontalAlignment="Left" Height="23" Margin="337,23,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" LostFocus="LeaveField" />
        <RadioButton Content="RadioButton" HorizontalAlignment="Left" Margin="88,92,0,0" VerticalAlignment="Top"/>
        <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="252,96,0,0" VerticalAlignment="Top"/>
        <ComboBox Name="combo" IsEditable="False" Text="aaa" IsReadOnly="True"
                  HorizontalAlignment="Left" Margin="337,89,0,0" VerticalAlignment="Top" Width="120" 
                  Focusable="True" GotFocus="ComboBoxGotFocused" >
            <ComboBoxItem>January</ComboBoxItem>
            <ComboBoxItem>February</ComboBoxItem>
        </ComboBox>
        <TextBlock HorizontalAlignment="Left" Height="40" Margin="260,184,0,0" TextWrapping="Wrap" Text="Text_Block" VerticalAlignment="Top" Width="257"/>

    </Grid>
</Window>

3 个答案:

答案 0 :(得分:82)

在WPF中,某些“容器”控件会自动调整其内容的大小,而有一些则不会。

以下是调整其内容大小的一些内容(我猜你正在使用其中一个或多个):

StackPanel
WrapPanel
Canvas
TabControl

以下是调整其内容的一些内容:

Grid
UniformGrid
DockPanel

因此,除非您希望自动调整大小,否则几乎总是优先使用Grid而不是StackPanel。请注意,Grid 大小的内部控件仍然可以......这一切都取决于您的Grid.RowDefinitionGrid.ColumnDefinition设置:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100" /> <!--<<< Exact Height... won't resize -->
        <RowDefinition Height="Auto" /> <!--<<< Will resize to the size of contents -->
        <RowDefinition Height="*" /> <!--<<< Will resize taking all remaining space -->
    </Grid.RowDefinitions>
</Grid>

您可以在MSDN上的Grid Class页面上找到有关Grid控件的更多信息。您还可以从MSDN上的WPF Container Controls Overview页面了解有关这些容器控件的更多信息。

使用FrameworkElement.HorizontalAlignmentFrameworkElement.VerticalAlignment属性可以进一步调整大小。这些属性的默认值为Stretch,它将拉伸元素以适合其包含控件的大小。但是,当它们设置为任何其他值时,元素将拉伸。

更新&gt;&gt;&gt;

回答评论中的问题:

使用Grid.RowDefinitionGrid.ColumnDefinition设置首先组织基本结构...如果需要,通常会将Grid控件添加到外部Grid控件的单元格中是。您还可以使用Grid.ColumnSpanGrid.RowSpan属性来启用控件以跨越Grid的多个列和/或行。

最常见的是,至少有一个行/列的Height / Width "*"将填充所有剩余空间,但是您可以使用这两个或更多设置,在这种情况下,剩余空间将在两个(或更多)行/列之间分割。 “自动”是用于未设置为“”*“'的行/列的好设置,但它实际上取决于您希望布局的方式。

您可以在单元格中的控件上使用Auto设置,但这也是如此,因为我们希望Grid为我们调整控件的大小...因此,我们根本不想设置这些控件的HeightWidth

我对FrameworkElement.HorizontalAlignmentFrameworkElement.VerticalAlignment属性的观点只是为了让您知道它们的存在......因为它们的默认值已经是Stretch,您不需要通常需要明确设置它们。

Margin属性通常仅用于将控件均匀分开...如果从Visual Studio工具箱中拖放控件,VS将设置Margin属性以准确放置控件放弃它的地方,但一般来说,这是不是我们想要的东西,因为它会混淆控件的自动调整大小。如果您这样做,那么只需删除或编辑Margin属性以满足您的需求。

答案 1 :(得分:3)

嗯,这很简单。

在窗口调整大小事件处理程序上,计算窗口增长/缩小的程度,并使用该分数进行调整1)高度,2)宽度,3)Canvas.Top,4)所有子项的Canvas.Left属性画布内的控件。

以下是代码:

24

答案 2 :(得分:0)

我以为我会与需要更清楚地实现这一目标的任何人分享这一点:

myCanvas 是Canvas控件,也是所有其他控制器的父级。该代码可以将大小调整为1366 x 768以上的任何分辨率。经过测试的4k分辨率4096 x 2160

记下所有MainWindow属性设置(WindowStartupLocation,SizeToContent和WindowState)-这对于正常工作很重要-我的用例要求的WindowState已最大化

xaml

<Window x:Name="mainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyApp" 
    xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    x:Class="MyApp.MainWindow" 
     Title="MainWindow"  SizeChanged="MainWindow_SizeChanged"
    Width="1366" Height="768" WindowState="Maximized" WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">

    <Canvas x:Name="myCanvas" HorizontalAlignment="Left" Height="768" VerticalAlignment="Top" Width="1356">
        <Image x:Name="maxresdefault_1_1__jpg" Source="maxresdefault-1[1].jpg" Stretch="Fill" Opacity="0.6" Height="767" Canvas.Left="-6" Width="1366"/>

        <Separator Margin="0" Background="#FF302D2D" Foreground="#FF111010" Height="0" Canvas.Left="-811" Canvas.Top="148" Width="766"/>
        <Separator Margin="0" Background="#FF302D2D" Foreground="#FF111010" HorizontalAlignment="Right" Width="210" Height="0" Canvas.Left="1653" Canvas.Top="102"/>
        <Image x:Name="imgscroll" Source="BcaKKb47i[1].png" Stretch="Fill" RenderTransformOrigin="0.5,0.5" Height="523" Canvas.Left="-3" Canvas.Top="122" Width="580">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="89.093"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>

.cs

 private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        myCanvas.Width = e.NewSize.Width;
        myCanvas.Height = e.NewSize.Height;

        double xChange = 1, yChange = 1;

        if (e.PreviousSize.Width != 0)
            xChange = (e.NewSize.Width / e.PreviousSize.Width);

        if (e.PreviousSize.Height != 0)
            yChange = (e.NewSize.Height / e.PreviousSize.Height);

        ScaleTransform scale = new ScaleTransform(myCanvas.LayoutTransform.Value.M11 * xChange, myCanvas.LayoutTransform.Value.M22 * yChange);
        myCanvas.LayoutTransform = scale;
        myCanvas.UpdateLayout();
    }