TabItem 中的 ContentControl 不会适当地调整大小

ContentControl inside TabItem doesn't resize proberly

我在 TabItem 里面有一个 ContentControlContentControl 显示一个 UserControl。我的问题是 ContentControlWidth 没有正确设置,它太大了。 Height 正确显示。 我想 SizeToContent 因为我有多个不同大小的 TabItems。 我有以下代码:

MainWindow.xaml(精简版)

<Window Height="350" Width="525" SizeToContent="WidthAndHeight">
<DockPanel>
    <TabControl DockPanel.Dock="Left" TabStripPlacement="Left">
        <TabItem Header="BDE Config" IsEnabled="{Binding LoggedIn}">
            <Grid>
                <ContentControl Content="{Binding CurrentViewModel}" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"/>
            </Grid>
        </TabItem>
    </TabControl>
</DockPanel>

UserControl 没有 Width/Height Properties。那么,为什么 Height 是正确的,而 Width 对我的屏幕来说却很大。

用户控件的

XAML:

<UserControl x:Class="BDE_Config2015.Views.BDEConfig"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:BDE_Config2015"
         xmlns:h="clr-namespace:BDE_Config2015.Helpers"
         mc:Ignorable="d" 
         Background="{StaticResource AppBg}" d:DesignHeight="655" d:DesignWidth="1180">    
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <!--1-->
    <GroupBox Grid.Column="0" Grid.Row="0" Header="BDE-Benutzer">
        <ComboBox Height="23" DisplayMemberPath="Benutzername" SelectedValuePath="Kbez" ItemsSource="{Binding BDEConfigModel.BDEBenutzer}" SelectedValue="{Binding CurrentUser}" />
    </GroupBox>
    <!--2-->
    <TabControl Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Background="Transparent" Margin="0,3,0,0">
        <TabItem Header="BDE">
            <Grid x:Name="gBDEKonfig">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition />
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="80"/>
                    <ColumnDefinition Width="80"/>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition Width="70"/>
                    <ColumnDefinition Width="80"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <!--Row 0-->
                <TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Text="Buttons pro Reiter" VerticalAlignment="Center" Visibility="Collapsed" />
                <TextBox Grid.Column="2" Grid.Row="0" Name="txtBDEReiter" Margin="0,0,0,5" Visibility="Collapsed" />
                <TextBlock Grid.Column="3" Grid.Row="0" Text="Hintergrundfarbe" VerticalAlignment="Center" Margin="10,0,0,0" Visibility="Collapsed" />
                <TextBox Grid.Column="4" Grid.Row="0" Margin="0,0,0,5" Visibility="Collapsed" />
                <Button Grid.Column="5" Grid.Row="0" Margin="10,0,0,5" Visibility="Collapsed">...</Button>
                <!--Row 1-->
                <TextBlock Grid.Column="0" Grid.Row="1" Text="BDE-Titel" VerticalAlignment="Top"/>
                <TextBox Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="1" Margin="0,0,0,5" Text="{Binding BDETitel, UpdateSourceTrigger=LostFocus}" KeyDown="TextBox_KeyDown" />
                <!--Row 2-->
                <TextBlock Grid.Column="0" Grid.Row="2" Text="BDE-Belegung"/>
                <!--Row 3-->
                <DataGrid Grid.Column="0" Grid.ColumnSpan="8" Grid.Row="3" ItemsSource="{Binding BDEConfigModel.Clientoptionen}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False"
                              SelectedValue="{Binding crBDEBelegung}" Name="dgvBDEBelegung" CellEditEnding="DGV_CellEditEnding" CurrentCellChanged="DGV_CurrentCellChanged"
                              h:DataGridBehavior.AutoScrollIntoView="True" SelectionMode="Single">
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding Nummer, UpdateSourceTrigger=LostFocus}" Header="Nr" />
                        <DataGridTextColumn Binding="{Binding OptionText, UpdateSourceTrigger=LostFocus}" Header="Arbeitsplatztitel" />
                        <DataGridTextColumn Binding="{Binding OptionInfo, UpdateSourceTrigger=LostFocus}" Header="Buttonbezeichnung"/>
                        <DataGridTemplateColumn Header="Anlage" Width="*">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox DisplayMemberPath="Anlage" SelectedValuePath="FertigungsStättenID" SelectedValue="{Binding OptionZahl}" IsTextSearchEnabled="True"
                                                  ItemsSource="{Binding Path=DataContext.BDEConfigModel.Fertigungsstaette, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" 
                                                  SelectedItem="{Binding Path=DataContext.siFertigungsstaette, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=OneWayToSource}">
                                    </ComboBox>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTemplateColumn Header="Arbeitsplatz" Width="*">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox DisplayMemberPath="Arbeitsplatzbez" SelectedValuePath="ArbeitsPlatzNummer" SelectedValue="{Binding OptionGanzzahl}" IsTextSearchEnabled="True"
                                                  ItemsSource="{Binding Path=DataContext.BDEConfigModel.Arbeitsplatz, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
                                                  SelectedItem="{Binding Path=DataContext.siArbeitsplatz, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=OneWayToSource}">
                                    </ComboBox>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>
                <!--Row 4-->
                <Button Grid.Column="0" Grid.Row="4" Margin="5" Command="{Binding NeuBDEBelegungCommand}">Neu</Button>
                <Button Grid.Column="1" Grid.Row="4" Margin="5" Command="{Binding LoeschenBDEBelegungCommand}">Löschen</Button>
            </Grid>
        </TabItem>
        <TabItem Header="Arbeitsgang/Arbeitsplan">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" Text="Arbeitsplan"/>
                <DataGrid Grid.Row="1">

                </DataGrid>
                <CheckBox Grid.Row="2" HorizontalAlignment="Right" Content="Unabhängig vom Arbeitsplan" Margin="0,10,5,0" />
                <TextBlock Grid.Row="3" Text="Arbeitsgang"/>
                <DataGrid Grid.Row="4">

                </DataGrid>
            </Grid>
        </TabItem>
        <TabItem Header="ColumnsManagement">
            <Grid Margin="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" Text="Arbeitsplatz" Margin="5,0" />
                    <ComboBox Grid.Column="1" Margin="5,0,5,5" ItemsSource="{Binding BDEConfigModel.BDEArbeitsplatz}" DisplayMemberPath="OptionText" SelectedValuePath="PKID" 
                              SelectedValue="{Binding SelectedArbeitsplatzCM}" />
                    <TextBlock Grid.Column="2" Text="DataSource" Margin="5,0" />
                    <ComboBox Grid.Column="3" Margin="5,0,5,5" SelectedValue="{Binding SelectedDataSource}">
                        <ComboBox.ItemsSource>
                            <x:Array Type="sys:String" xmlns:sys="clr-namespace:System;assembly=mscorlib">
                                <sys:String>proc_BDEoW_ChargeStartDetail</sys:String>
                                <sys:String>proc_BDEoW_ChargeProduktion</sys:String>
                            </x:Array>
                        </ComboBox.ItemsSource>
                    </ComboBox>
                    <Button Grid.Column="4" Content="Laden" Width="85" HorizontalAlignment="Right" Margin="5,0,5,5" Command="{Binding LadenCMCommand}"/>
                </Grid>
                <DataGrid Grid.Row="1" ItemsSource="{Binding BDEConfigModel.ArbeitsplatzSpaltenManagement}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False" 
                          IsEnabled="{Binding EnabledCM}" SelectedValue="{Binding crArbeitsplatzSM}" h:DataGridBehavior.AutoScrollIntoView="True">
                    <DataGrid.Columns>
                        <DataGridTextColumn Width="Auto" Header="Spalte" Binding="{Binding SQLVisibleColumns}" />
                        <DataGridTextColumn Width="*" Header="Titel" Binding="{Binding SQLVisibleColumnsName}" />
                        <DataGridTextColumn Width="*" Header="%Weite" Binding="{Binding SQLVisibleColumnsWidth}" />
                        <DataGridTextColumn Width="*" Header="ReadOnly" Binding="{Binding SQLVisibleColumnsAccess}" />
                    </DataGrid.Columns>
                </DataGrid>
                <TextBlock Grid.Row="2" Text="{Binding MessageCM}" HorizontalAlignment="Stretch" Margin="5,0,5,0" />
                <Grid Grid.Row="3">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Button Grid.Column="0" Content="Neu" Margin="5" Command="{Binding NeuCMCommand}" IsEnabled="{Binding EnabledCM}" />
                    <Button Grid.Column="1" Content="Löschen" Margin="5" Command="{Binding LoeschenCMCommand}" IsEnabled="{Binding EnabledCM}" />
                    <Button Grid.Column="2" Content="Con. Kopieren" Margin="5" Command="{Binding KopierenCMCommand}" IsEnabled="{Binding EnabledCM}" />
                    <TextBox Grid.Column="3" IsReadOnly="True" Margin="5" Text="{Binding SummeCM}"/>
                    <Button Grid.Column="4" Content="Speichern" Margin="5" Command="{Binding SpeichernCMCommand}" IsEnabled="{Binding EnabledCM}" />
                </Grid>
            </Grid>
        </TabItem>
    </TabControl>
    <!--3-->
    <GroupBox Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" Header="Modul-Info" Name="gbModulInfo" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition />
                <ColumnDefinition Width="80"/>
            </Grid.ColumnDefinitions>
            <DataGrid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" ItemsSource="{Binding BDEConfigModel.BDEModul}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False"
                      SelectedValue="{Binding crModulInfo}" h:DataGridBehavior.AutoScrollIntoView="True">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Typ}" Header="Typ" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Bezeichnung}" Header="Bezeichnung" Width="*" IsReadOnly="True" />
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Column="0" Grid.Row="1" Content="V Spez." Margin="5" Command="{Binding VSpezCommand}"/>
            <Button Grid.Column="2" Grid.Row="1" Content="V Global" Margin="5" Command="{Binding VGlobalCommand}"/>
        </Grid>
    </GroupBox>
    <!--4-->
    <GroupBox Grid.Column="0" Grid.Row="2" Header="Register" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <Grid Name="gRegister">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="30" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <DataGrid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" ItemsSource="{Binding BDEConfigModel.Register}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False"
                      SelectedValue="{Binding crRegister}" h:DataGridBehavior.AutoScrollIntoView="True" CellEditEnding="DGV_CellEditEnding" CurrentCellChanged="DGV_CurrentCellChanged">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Nummer, UpdateSourceTrigger=LostFocus}" Header="Nr" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding OptionText, UpdateSourceTrigger=LostFocus}" Header="Registername" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Column="0" Grid.Row="1" Content="Neu" Margin="5" Command="{Binding NeuRegisterCommand}" />
            <Button Grid.Column="1" Grid.Row="1" Content="Löschen" Margin="5" Command="{Binding LoeschenRegisterCommand}" />
        </Grid>
    </GroupBox>
    <!--5-->
    <GroupBox Grid.Column="1" Grid.Row="3" Header="Spez. Modulzuordnung" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <DataGrid Name="dgvMZ" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" ItemsSource="{Binding BDEConfigModel.BDEMZ}" AutoGenerateColumns="False" CanUserAddRows="False"
                         CanUserReorderColumns="False" SelectedValue="{Binding crMZ}" h:DataGridBehavior.AutoScrollIntoView="True" CellEditEnding="DGV_CellEditEnding" CurrentCellChanged="DGV_CurrentCellChanged">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Modul}" Header="Typ" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Modullevel, UpdateSourceTrigger=LostFocus}" Header="Level" />
                    <DataGridTextColumn Binding="{Binding Parameter1, UpdateSourceTrigger=LostFocus}" Header="Parameter" Width="*" />
                    <DataGridTextColumn Binding="{Binding ModulSetup, UpdateSourceTrigger=LostFocus}" Header="Setup" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Column="0" Grid.Row="1" Content="Löschen" Margin="5" Command="{Binding LoeschenMZCommand}"/>
        </Grid>
    </GroupBox>
    <!--6-->
    <GroupBox Grid.Column="2" Grid.Row="3" Header="Global Modulzuordnung" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <DataGrid Name="dgvMZGlobal" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" ItemsSource="{Binding BDEConfigModel.BDEMZGlobal}" AutoGenerateColumns="False" CanUserAddRows="False"
                      CanUserReorderColumns="False" SelectedValue="{Binding crMZGlobal}" h:DataGridBehavior.AutoScrollIntoView="True" CellEditEnding="DGV_CellEditEnding" 
                      CurrentCellChanged="DGV_CurrentCellChanged">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Modul}" Header="Typ" IsReadOnly="True"/>
                    <DataGridTextColumn Binding="{Binding Modullevel, UpdateSourceTrigger=LostFocus}" Header="Level"/>
                    <DataGridTextColumn Binding="{Binding Parameter1, UpdateSourceTrigger=LostFocus}" Header="Parameter" Width="*"/>
                    <DataGridTextColumn Binding="{Binding ModulSetup, UpdateSourceTrigger=LostFocus}" Header="Setup" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Column="0" Grid.Row="1" Content="Löschen" Margin="5" Command="{Binding LoeschenMZGlobalCommand}"/>
        </Grid>
    </GroupBox>
</Grid>

这似乎与 window 上的 SizeToContent 属性 和数据网格列上的 "star-sizing" 之间的奇怪交互有关。

要么将 window 的 SizeToContent 属性 设置为 Height 并明确设置 window 的宽度,要么限制通过将它们的 MaxWidth 属性设置为某个合适的限制来设置星号大小的列。

This thread on CodePlex描述了问题。显然事情过去更糟,因为会抛出异常!来自该线程最底部的 post:

The exception has been fixed but it's still not working properly. When placed in a user control with (sic) doesn't have a fixed width, setting "*" on column width will cause the column to be extremely wide (several thousand pixel), and this happens both at design time and run time.


顺便说一句,您可以使用 StackPanelDockPanel 容器而不是使用 很多 的 XAML 标记一个 Grid 代表一切。

经过更多尝试,我找到了适合我的答案。我做了以下事情:

MaxWidth="{x:Static SystemParameters.PrimaryScreenWidth}" WindowStartupLocation="CenterScreen" Left="{Binding winLeft, Mode=TwoWay}" Top="{Binding winTop, Mode=TwoWay}"

它设置 WindowMaxWidthScreen Width,然后每当加载带有 Star-Sized ColumnsUser Control 时,它也会设置 Position 到 0,0.