WPF中的Dock和Anchor

时间:2013-10-03 18:39:34

标签: c# wpf

我来自WinForms背景,我开始学习WPF。我在Pluralsight上经历过一系列教程,但在处理调整大小时遇到​​了一些困难。

调整大小时,我的文本框似乎没有按照我想要的方式“锚定”。我将下面的xaml包含在其中的注释中,以了解我正在寻找的行为。任何有关最佳实践的反馈都将非常感谢。代码对我来说“感觉”有点尴尬,但我不确定这是不是因为它对我来说只是新手,或者是否有更容易/更好的方式来做我正在尝试的事情。

要想知道事情的样子而不需要加载下面的XAML - 这里是在调整表单截图之前和之后。 Before Resize http://dboasis.com/screenshots/beforeresize.jpg After Resize http://dboasis.com/screenshots/afterresize.jpg

我希望看到如何处理调整大小问题的建议,以及在看到我在XAML中尝试这样做之后的最佳实践。

此外 - xaml确实实现了DevExpress控件 - 如果有人要我重做表单而不使用第三方控件以便他们更容易提出建议,我很乐意这样做。

<dx:DXWindow
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
    xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" x:Class="DXTemplateSandbox.MainWindow"
    Title="MainWindow" Height="437" Width="641">
<Grid>
    <dx:DXTabControl x:Name="tabcntMainTab">
        <dx:DXTabItem x:Name="tabUserList" Header="User List">
            <Grid Background="Transparent">

                <Grid.RowDefinitions>
                    <RowDefinition x:Name="SelectLabel" Height="30" />
                    <RowDefinition x:Name="OpenDataFile" Height="34" />
                    <RowDefinition x:Name="DataGridLayoutRow" Height="185*" />
                    <RowDefinition x:Name="AppPrefsInfo" Height="110" />
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0">
                    <!-- 
                    The DataFileLocation not resizing the width.  How do I instead lock the vertical size, but allow width to
                    resize with form?
                    -->
                    <TextBox Name="DataFileLocation" Width="419" Margin="0,5" HorizontalAlignment="Stretch" />

                    <!--
                    How do I get the SelectData button stay immediately to the right of the DatFileLocation textbox when resizing?
                    -->
                    <Button Name="SelectData" Content="..." Width="40" Margin="5" Click="SelectData_Click"/>
                    <DockPanel>
                        <!-- I would like the "Go" button to stay anchored to the right when resizing. -->
                        <Button x:Name="GoButton" 
                                Content="Go" 
                                Width="66" 
                                DockPanel.Dock="Right"
                                HorizontalAlignment="Right"
                                VerticalAlignment="Top"
                                Margin="50,5,5,5" 
                                Click="GoButton_Click" />
                    </DockPanel>

                </StackPanel>

                <!--
                -->
                <dxg:GridControl Grid.Row="2" Margin="5" >
                    <dxg:GridControl.View>
                        <dxg:TableView ShowGroupPanel="False"/>
                    </dxg:GridControl.View>
                </dxg:GridControl>

                <Label Content="Select Data File" HorizontalAlignment="Left" Margin="5,5,0,0" VerticalAlignment="Top" Height="26" Grid.RowSpan="2" Width="91"/>

                <!-- 
                Is using a grid inside a parent grid cell the best way of doing this?  I'm using stackpanels in each of the rows in the
                child grid.  Is there a better way of doing this?  
                -->
                <Grid x:Name="AppPrefsGrid" Grid.Row="3" >
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <!--
                    Ideally I would like the text boxes to grow and shrink at the same rate as form is resized, and leave the labels the same width.  I don't know
                    if this is practical however.
                    -->
                    <StackPanel Grid.Row="0" Orientation="Horizontal">
                        <Label Content="Registration Name:" Width="112" Margin="5"/>
                        <TextBox Name="RegNameTextBox" Width="175" Margin="5" IsEnabled="False"/>
                        <Label Content="Install Date:" Width="84" Margin="10,5,5,5"/>
                        <TextBox Name="InstallDateTextBox" Width="175" Margin="5" IsEnabled="False"/>
                    </StackPanel>
                    <StackPanel Grid.Row="1" Orientation="Horizontal">
                        <Label Content="Registration Number:" Width="112" Margin="5"/>
                        <TextBox Name="RegNumberTextBox" Width="175" Margin="5" IsEnabled="False"/>
                        <Label Content="Data File Version:" Width="84" Margin="10,5,5,5"/>
                        <TextBox Name="DataVersionTextBox" Width="175" Margin="5" IsEnabled="False"/>
                    </StackPanel>
                    <StackPanel Grid.Row="2" Orientation="Horizontal">
                        <Label Content="Edition Code:" Width="112" Margin="5"/>
                        <TextBox Name="EditionCodeTextBox" Width="175" Margin="5" IsEnabled="False"/>
                        <Label Content="User Count:" Width="84" Margin="10,5,5,5"/>
                        <TextBox Name="UserCountTextBox" Width="175" Margin="5" IsEnabled="False"/>
                    </StackPanel>


                </Grid>

            </Grid>

        </dx:DXTabItem>
        <dx:DXTabItem x:Name="tabKeyGen" Header="Key Generator"/>
    </dx:DXTabControl>
</Grid>

1 个答案:

答案 0 :(得分:5)

这里有多个问题似乎是因为您没有为控件使用正确的布局面板。

默认情况下,控件的大小取决于父级的行为。

例如,放置在Grid内的项目将拉伸以填充网格单元格内给予它们的所有可用空间。如果网格行/列定义的高度/宽度设置为Auto,则意味着它将以控件所需的任何大小绘制控件。如果将其设置为固定大小(例如100),则会以该大小绘制控件。如果它设置为*大小,它将使用剩余空间的百分比绘制控件。

此行为可以由控件本身的属性覆盖,例如HorizontalAlignmentVerticalAlignment,或设置HeightWidth和{{等属性1}}。

因此,为了解决您的一些具体问题,首先要删除托管标签/文本框组合的堆叠面板,然后用适当的3x4 Margin替换它们。将标签放在第0列和第2列中,并为Grid提供固定大小。将TextBox放在第1列和第3列中,并将它们保留为ColumnDefinition大小。请注意,*大小是一个百分比,因此一列中的2 *和另一列中的3 *表示总共有*个,而第1列将占用2/5的空间column2将占用空间的3/5。

要在表单调整大小时让5*调整大小,只需删除DataFileLocation属性,然后将其大小调整为网格单元格的大小。

要让Width按钮停留在SelectData文本框右侧,请将它们放在SelectData中。将Button停靠在右侧,并允许TextBox填充所有剩余空间。如果希望tab键按预期循环显示,则必须设置TabIndex。

DockPanel

从那开始,看看它的样子。您的父网格的RowDefinition看起来是正确的(除了您的第3行高度应为<DockPanel> <Button DockPanel.Dock="Right" ... /> <TextBox ... /> </DockPanel> 而不是"*"),这应该意味着您的DevExpress控件应该拉伸/收缩以填充所有剩余的垂直空间