46

当我单击最大化按钮时,窗口最大化,但控件没有按比例调整大小。使控件相应调整大小的最佳方法是什么?我正在使用 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>
4

3 回答 3

107

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

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

StackPanel
WrapPanel
Canvas
TabControl

以下是一些确实会调整其内容的大小:

Grid
UniformGrid
DockPanel

因此,除非您希望发生自动调整大小,否则几乎总是最好使用 aGrid而不是 a 。请注意,仍然可以不调整其内部控件的大小……这完全取决于您的设置:StackPanelGridGrid.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 上的Class页面中找到有关该Grid控件的更多信息。您还可以从 MSDN 上的WPF 容器控件概述页面中找到有关这些容器控件的更多信息。Grid

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

更新>>>

针对您评论中的问题:

首先使用Grid.RowDefinitionandGrid.ColumnDefinition设置来组织一个基本结构...如果需要,通常将Grid控件添加到外部Grid控件的单元格中。您还可以使用Grid.ColumnSpanGrid.RowSpan属性使控件能够跨越Grid.

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

没有Auto可以在单元格中的控件上使用的设置,但这也是一样的,因为我们希望Grid为我们调整控件的大小......因此,我们不想将这些控件的Heightor设置为Width全部。

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

Margin属性通常仅用于将控件均匀分布...如果您从 Visual Studio 工具箱拖放控件,VS 将设置该Margin属性以将控件准确放置在您放置的位置,但通常,这不是我们想要的因为它会弄乱控件的自动调整大小。如果您这样做,则只需删除或编辑该Margin属性以满足您的需要。

于 2013-10-16T08:24:46.813 回答
2

嗯,这很简单。

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

这是代码:

private void window1_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);

            foreach (FrameworkElement fe in myCanvas.Children )
            {   
                /*because I didn't want to resize the grid I'm having inside the canvas in this particular instance. (doing that from xaml) */            
                if (fe is Grid == false)
                {
                    fe.Height = fe.ActualHeight * yChange;
                    fe.Width = fe.ActualWidth * xChange;

                    Canvas.SetTop(fe, Canvas.GetTop(fe) * yChange);
                    Canvas.SetLeft(fe, Canvas.GetLeft(fe) * xChange);

                }
            }
        }
于 2016-09-08T13:22:23.533 回答
2

只是想我会与任何需要更清楚地了解如何实现这一目标的人分享这个:

myCanvas是一个 Canvas 控件,是所有其他控制器的父级。此代码可以巧妙地将大小调整为 1366 x 768 以上的任何分辨率。经测试高达 4k 分辨率 4096 x 2160

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

xml

<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();
    }
于 2019-11-21T09:07:40.497 回答