Wpf 网格创建我不需要的额外间距';我不想要

Wpf 网格创建我不需要的额外间距';我不想要,wpf,visual-studio-2010,visual-studio-2012,grid,Wpf,Visual Studio 2010,Visual Studio 2012,Grid,我使用嵌套网格在WPF应用程序中创建了一个较大的输入表单。我正在使用VS2010和VS2012 Ultimate 代码如下: <Window x:Class="Gridtest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWi

我使用嵌套网格在WPF应用程序中创建了一个较大的输入表单。我正在使用VS2010和VS2012 Ultimate

代码如下:

<Window x:Class="Gridtest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow">

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="16*"/>
        <ColumnDefinition Width="10*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid Grid.Column="0" Grid.Row="0" Grid.RowSpan="2">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="136*"/>
            <ColumnDefinition Width="271*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Battery Name"/>
        <Label Grid.Row="1" Grid.Column="0" Content="FDC Callsign"/>
        <Label Grid.Row="2" Grid.Column="0" Content="Battery Type"/>
        <Label Grid.Row="3" Grid.Column="0" Content="GRID"/>
        <Label Grid.Row="4" Grid.Column="0" Content="ALT"/>
        <Label Grid.Row="5" Grid.Column="0" Content="Dir. of Fire"/>
        <Label Grid.Row="6" Grid.Column="0" Content="Target Prefix"/>
        <Label Grid.Row="7" Grid.Column="0" Content="Target # Start"/>

        <Grid Grid.Column="1" Grid.ColumnSpan="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <ComboBox x:Name="EBattName"  IsEditable="True" ItemsSource="{Binding BatteryList}" SelectedItem="{Binding SelectedBattery, Mode=TwoWay}" DisplayMemberPath="Name"/>
            <Button x:Name="EBattSave" Grid.Column="1" Content="Add"/>
        </Grid>
        <TextBox x:Name="EBattCallsign" Grid.Row="1" Grid.Column="1" DataContext="{Binding SelectedBattery}" Text="{Binding Callsign}" Grid.ColumnSpan="2"/>
        <ComboBox x:Name="EBattType" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding SelectedBattery}" SelectedItem="{Binding BWeapon}" DisplayMemberPath="Designation"/>
        <TextBox x:Name="EBattGrid" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding SelectedBattery}" Text="{Binding Coords.Grid}"/>
        <TextBox x:Name="EBattAlt" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding SelectedBattery}" Text="{Binding Coords.Altitude}"/>
        <TextBox x:Name="EBattDir" Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding SelectedBattery}" Text="{Binding Dir}"/>
        <TextBox x:Name="EBattPre" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding SelectedBattery}" Text="{Binding Prefix}"/>
        <TextBox x:Name="EBattStart" Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding SelectedBattery}" Text="{Binding Start}"/>
    </Grid>

    <Grid Grid.Column="0" Grid.Row="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Label Grid.ColumnSpan="3" Content="NEW MISSION"/>

        <Button x:Name="BMissionGrid" Grid.Row="1" Content="GRID"/>
        <Button x:Name="BMissionPolar" Grid.Column="1"  Grid.Row="1" Content="POLAR"/>
        <Button x:Name="BMissionShift" Grid.Column="2"  Grid.Row="1" Content="SHIFT"/>
    </Grid>

    <!-- Adding negative bottom margin to this grid helps... -->
    <Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Grid.ColumnSpan="2" Content="OBSERVER INFORMATION"/>

        <Label Grid.Row="1" Grid.Column="0" Content="Select"/>
        <Label Grid.Row="2" Grid.Column="0" Content="Name"/>
        <Label Grid.Row="3" Grid.Column="0" Content="Grid"/>
        <Label Grid.Row="4" Grid.Column="0" Content="Alt"/>


        <Grid  Grid.Row="1" Grid.Column="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <ComboBox Grid.Column="0" x:Name="EObsSelect" ItemsSource="{Binding SelectedBattery.Observers}" SelectedItem="{Binding SelectedObserver, Mode=TwoWay}" DisplayMemberPath="Name" />
            <Button Grid.Column="1" x:Name="BObserverAdd" Content="New"/>
        </Grid>

        <TextBox x:Name="EObsName" Grid.Row="2" Grid.Column="1" Text="{Binding SelectedObserver.Name}"          />
        <TextBox x:Name="EObsGrid" Grid.Row="3" Grid.Column="1" Text="{Binding SelectedObserver.Coord.Grid}"    />
        <TextBox x:Name="EObsAlt" Grid.Row="4" Grid.Column="1"  Text="{Binding SelectedObserver.Coord.Altitude}"/>

        <Label Grid.ColumnSpan="2" Grid.Row="5" Content="KNOWN POINTS"/>

        <Label Grid.Row="6" Grid.Column="0" Content="Select"/>
        <Label Grid.Row="7" Grid.Column="0" Content="Name"/>
        <Label Grid.Row="8" Grid.Column="0" Content="Grid"/>
        <Label Grid.Row="9" Grid.Column="0" Content="Alt"/>

        <Grid  Grid.Row="6" Grid.Column="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <ComboBox x:Name="EKPSelect" Grid.Column="0" ItemsSource="{Binding SelectedBattery.Knownpoints}" SelectedItem="{Binding SelectedPoint, Mode=TwoWay}" DisplayMemberPath="Name"/>
            <Button Grid.Column="1" x:Name="BKnownpointAdd" Content="New"/>
        </Grid>

        <TextBox x:Name="EKPName" Grid.Row="7" Grid.Column="1"  Text="{Binding SelectedItem.Name, ElementName=EKPSelect}"          />
        <TextBox x:Name="EKPGrid" Grid.Row="8" Grid.Column="1"  Text="{Binding SelectedItem.Coord.Grid, ElementName=EKPSelect}"    />
        <TextBox x:Name="EKPAlt" Grid.Row="9" Grid.Column="1"   Text="{Binding SelectedItem.Coord.Altitude, ElementName=EKPSelect}"/>
    </Grid>


    <Grid Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="MISSION LIST"/>

        <ListView Grid.Row="1" SelectionMode="Single"
            DataContext="{Binding SelectedBattery}"
            ItemsSource="{Binding Missions}"
                  >
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding TargetNumber}" Header="Target No"/>
                    <GridViewColumn DisplayMemberBinding="{Binding TargetDescription}" Header="Description"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Coords.Grid}" Header="Location"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Coords.Altitude}" Header="Altitude"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Attitude}" Header="Attitude"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Length}" Header="Length"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Radius}" Header="Radius"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Notes}" Header="Remarks"/>
                </GridView>
            </ListView.View>
        </ListView>

    </Grid>

</Grid>

我从我的项目中提取了它,并删除了指向我的项目名称空间的所有事件处理程序和绑定,因此您可以将其粘贴到新的WPF应用程序项目中,并亲自查看

以下是生成的窗口:

设计视图:(用红色标记的额外间距)
运行时视图:

它应该是什么样子的ASCII视图:

--------------- | 1 | | --------| 3 | | 2 | | --------------- | 4 | --------------- --------------- | 1 | | --------| 3 | | 2 | | --------------- | 4 | --------------- 它创建了大量我不想要的垂直间距。 这是从哪里来的?如何修复它?正如我在上面的代码中所标记的,在其中一个网格中添加Margin=“0,0,0,-200”会有所帮助,但这看起来非常难看

我可能会从头开始重建网格,以减少嵌套,但在我看来,这似乎不应该发生

编辑:我用最小的嵌套重建了网格,所以它只是一个大网格,所有元素都放在其中:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/><!-- Left Labels -->
        <ColumnDefinition Width="10*"/><!-- Left Edit controls --> 
        <ColumnDefinition Width="Auto"/><!-- Right labels -->
        <ColumnDefinition Width="7*"/><!-- Right Edit controls -->
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" /> <!-- Everything in its own row -->
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*"    /> <!-- Listview in this row -->
    </Grid.RowDefinitions>

    <!-- Elements here -->

</Grid>


这样做没有任何明显的问题。

我在用您的代码进行测试时,发现了一些奇怪的行为。面板的渲染应如下所示:

--------------- | 1 | | --------| 3 | | 2 | | --------------- | 4 | ---------------
<StackPanel>
    <DockPanel>
        <Grid x:Name="3" DockPanel.Dock="Right" ... />
        <Grid x:Name="2" DockPanel.Dock="Top" ... />
        <Grid x:Name="1" ... />
    </DockPanel>
    <Grid x:Name="4" ... />
</StackPanel>
删除单元格#3中的大部分元素会正确地将单元格绘制到正确的高度,减少#3中的元素数量会缩小高度,但不会消除高度,因此可能与计算边距或填充有关

因此,我的建议是使RowSpan=2与第一个示例类似,或者更改面板布局,使其如下所示:

--------------- | 1 | | --------| 3 | | 2 | | --------------- | 4 | ---------------
<StackPanel>
    <DockPanel>
        <Grid x:Name="3" DockPanel.Dock="Right" ... />
        <Grid x:Name="2" DockPanel.Dock="Top" ... />
        <Grid x:Name="1" ... />
    </DockPanel>
    <Grid x:Name="4" ... />
</StackPanel>
或者切换到不具有此行为的其他
面板
,例如带有
LastChildFill=“False”
DockPanel
,或
StackPanel


嗯,但是剩余的空间从哪里来呢?我没有指定任何高度或最小高度。窗或格线是否有默认高度?我试图在随机位置添加一些Height=“*”行,但这并没有改变多少行为…@duk3luk3
窗口
对象的默认行为也是使其子对象占用所有可用空间。在WPF中,
面板
通常决定子对象的大小和布局,而不是子对象。当然,子对象也可以具有影响其位置和大小的属性(最小/最大高度/宽度、水平/垂直对齐等)。至于将
*
大小的行添加到何处,您需要将其添加到父
网格中,因为这是为其行分配额外空间的行。请参阅我答案的更新:)将Height=“*”行添加到父网格对我来说完全没有任何帮助。玩弄父网格行高度,并使其中几个高度为“*”会稍微改变行为,但仍然非常奇怪。@duk3luk3 Ahhh我明白你现在的意思了。这很奇怪,它看起来像是根据右边元素的边距或填充为列应用了额外的空间。如果删除那里的所有元素,多余的空间就会消失。只移除部分元素会减少空间,但不会消除空间。我建议使用
DockPanel
来代替您想要的布局,并将更新我的答案以反映这一点,但是我很好奇为什么它会这样:)@HighCore lol谢谢,但在这种情况下,我认为我的答案是错误的,我将编辑它:)我实际上对这种行为非常好奇,所以我特别问过。我希望得到一些关于为什么会发生这种情况的解释:)很好,我将密切关注(:你应该把你的解决方案作为自我回答发布。
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="16*"/>
    <ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/> <!-- 5th row to take up all available space -->
</Grid.RowDefinitions>