Wpf: Сетка: Как я могу поделиться шириной столбца / высоты строки? - PullRequest
5 голосов
/ 30 июля 2010

У меня есть сетка с 3 столбцами и 5 строками:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Grid.Column="0">Gas Volume Fraction</Label>
    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=GasVolumeFraction}" MinWidth="40"></TextBox>
    <Label Grid.Row="0" Grid.Column="2">-</Label>

    <Label Grid.Row="1" Grid.Column="0">Density</Label>
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Density}" MinWidth="40"></TextBox>
    <Label Grid.Row="1" Grid.Column="2">kg/m3</Label>

    <Label Grid.Row="2" Grid.Column="0" Content="Curve speed" Style="{StaticResource curveSpeed}" ></Label>
    <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Density}" Style="{StaticResource curveSpeed}" MinWidth="40"></TextBox>
    <Label Grid.Row="2" Grid.Column="2" Style="{StaticResource curveSpeed}">rpm</Label>

    <WrapPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3">
        <RadioButton>Delta pressure</RadioButton>
        <RadioButton>Head</RadioButton>
    </WrapPanel>

    <WrapPanel Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3">
        <RadioButton>Efficiency</RadioButton>
        <RadioButton>Power</RadioButton>
        <RadioButton>Torque</RadioButton>
    </WrapPanel>

</Grid>

Для текстовых полей и радиокнопок предъявляются разные требования к пространству, поэтому строки отображаются с разной высотой в зависимости от их содержимого. Как я могу сделать строки равномерного размера, но не больше, чем нужно? Другими словами: я хочу получить ту же высоту, что и параметр Height = "Auto" для строки, которая содержит текстовое поле (самый большой элемент в моей сетке), а затем использовать эту высоту для всех строк.

Ответы [ 4 ]

36 голосов
/ 11 августа 2011

Я знаю, что это старый вопрос, но я отвечу для всех, кто сталкивается с этим во время поиска в Google.

На самом деле существует очень простое решение этой проблемы с использованием SharedSizeScope, упомянутого Quartermeister.

<Grid IsSharedSizeScope="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" SharedSizeGroup="groupName" />
        <RowDefinition Height="Auto" SharedSizeGroup="groupName" />
        <RowDefinition Height="Auto" SharedSizeGroup="groupName" />
    </Grid.RowDefinitions>

    ...
</Grid>

Просто убедитесь, что для Grid.IsSharedSizeScope установлено значение true, и убедитесь, что у каждого RowDefinition есть одна и та же SharedSizeGroup, а строки должны быть автоматически и иметь одинаковый размер.Это работает и для столбцов.

13 голосов
/ 30 июля 2010

В идеале вы должны использовать строки со звездообразным размером, как у вас, и установить сетку на VerticalAlignment="Top", но, к сожалению, звездообразный размер не работает, когда размер сетки соответствует ее содержимому.

Вместо использования одной сетки, используйте UniformGrid для вертикальной компоновки с вложенными элементами управления сеткой для горизонтальной компоновки.Вы можете установить SharedSizeScope для столбцов во внутренних сетках, чтобы размеры столбцов были общими для них.

<UniformGrid Rows="5" VerticalAlignment="Top" Grid.IsSharedSizeScope="True">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0">Gas Volume Fraction</Label>
        <TextBox Grid.Column="1" Text="{Binding Path=GasVolumeFraction}" MinWidth="40"></TextBox>
        <Label Grid.Column="2">-</Label>
    </Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0">Density</Label>
        <TextBox Grid.Column="1" Text="{Binding Path=Density}" MinWidth="40"></TextBox>
        <Label Grid.Column="2">kg/m3</Label>
    </Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="Curve speed" Style="{StaticResource curveSpeed}"></Label>
        <TextBox Grid.Column="1" Text="{Binding Path=Density}" Style="{StaticResource curveSpeed}" MinWidth="40"></TextBox>
        <Label Grid.Column="2" Style="{StaticResource curveSpeed}">rpm</Label>
    </Grid>
    <WrapPanel>
        <RadioButton>Delta pressure</RadioButton>
        <RadioButton>Head</RadioButton>
    </WrapPanel>
    <WrapPanel>
        <RadioButton>Efficiency</RadioButton>
        <RadioButton>Power</RadioButton>
        <RadioButton>Torque</RadioButton>
    </WrapPanel>
</UniformGrid>
1 голос
/ 30 июля 2010

Вы можете использовать привязку к ActualWidth и ActualHeight вашего самого большого текстового блока.

    <Grid x:Name="grid" ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="{Binding Path=ActualHeight, ElementName=biggestTB}"/>
            <RowDefinition Height="{Binding Path=ActualHeight, ElementName=biggestTB}"/>                        
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=biggestTB}"/>
            <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=biggestTB}"/>                        
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" x:Name="biggestTB" Text="biggest textblock content" TextWrapping="Wrap"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="content" TextWrapping="Wrap"/>
    </Grid>
0 голосов
/ 17 марта 2019

Моя проблема похожа на приведенный выше вопрос, но немного отличается, потому что ни подход IsSharedSizeScope не решил ее для меня, ни Binding with ActualWidth.Итак, я публикую другое решение, надеясь, что кто-то найдет это полезным.Итак, вот проблема, которую мне нужно было решить:

У меня есть приложение, в котором у меня есть элемент управления с разделенным видом - см. Синюю часть ниже - и хотя мне нравится иметь GridSplitter в серединедисплей Я хочу реализовать синюю часть в отдельном элементе управления, в то время как часть сверху должна быть реализована в отдельной сборке: enter image description here ... но GridSplitter должен пройти весь путь через основнойпросматривать и соединять обе области, не имея представления о фактическом разделении.Я достиг этого, установив ширину столбцов при каждом перетаскивании TopSplitter или MainSplitter.

Этот подход не имеет штрафов за производительность и работает со столбцами размера *.* Оказывается, что синхронизация двух или более GridSplitters (как в этом случае) фактически требует от нас синхронизации ширины столбцов, которые «изменяются» с помощью GridSplitter.Перетащите Top- или MainSplitter, и вы увидите, что другая область изменяет размеры, как если бы это был один сплиттер: -)

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Grid Grid.Row="0" Margin="3,3,3,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" Name="TopColumnA"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" Name="TopColumnB"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="AntiqueWhite"
                   Margin="0,0,3,3"
                   />

        <GridSplitter
            Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Name="TopSplitter"
            HorizontalAlignment="Stretch"
            Background="Gray" Width="6"
            DragCompleted="GridSplitter_DragCompleted"
            DragDelta="MainSplitter_DragDelta"
            />

        <TextBlock Grid.Column="2" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="AntiqueWhite"
                   Margin="3,0,0,3"
                   />
    </Grid>

    <Grid Grid.Row="1" Margin="3,0,3,3">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" Name="MainColumnA"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" Name="MainColumnB"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="Aqua"
                   Margin="0,0,3,0"
                   />

        <GridSplitter
            Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Name="MainSplitter"
            HorizontalAlignment="Stretch"
            Background="Black" Width="6"
            DragCompleted="GridSplitter_DragCompleted"
            DragDelta="MainSplitter_DragDelta"
            />

        <TextBlock Grid.Column="2" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="Aqua"
                   Margin="3,0,0,0"
                   />
    </Grid>
</Grid>

... и вот необходимый код позади:

private void GridSplitter_DragCompleted(object sender, DragCompletedEventArgs e)
{
    if (sender == MainSplitter)
    {
        TopColumnA.Width = MainColumnA.Width;
        TopColumnB.Width = MainColumnB.Width;
    }
    else
    {
        if (sender == TopSplitter)
        {
            MainColumnA.Width = TopColumnA.Width;
            MainColumnB.Width = TopColumnB.Width;
        }
    }
}

private void MainSplitter_DragDelta(object sender, DragDeltaEventArgs e)
{
    if (sender == MainSplitter)
    {
        TopColumnA.Width = MainColumnA.Width;
        TopColumnB.Width = MainColumnB.Width;
    }
    else
    {
        if (sender == TopSplitter)
        {
            MainColumnA.Width = TopColumnA.Width;
            MainColumnB.Width = TopColumnB.Width;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...