Как я могу закрепить текстовое поле в wpf? - PullRequest
2 голосов
/ 26 мая 2010

У меня есть окно с вкладками. На одной из вкладок у меня есть макет, как показано ниже. (На самом деле все сложнее, у меня есть 4 текстовых поля подряд, и у меня есть больше строк.) Как я могу сделать, чтобы 3-е текстовое поле имело ширину надписи + ширину текстового поля выше, то есть правильно ли выровнены? Проблема в том, что WPF расширяет 3-е текстовое поле, когда я набираю в него текст. Использование жестко закодированных чисел для размеров побеждает всю цель WPF. Я мог бы сделать это в 10 раз быстрее в Windows Forms, чем в WPF.

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

альтернативный текст http://img28.imageshack.us/img28/3958/wpfanchor.png

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="3"/>
        </Style>
        <Style x:Key="SmallTextBox" TargetType="{x:Type TextBox}"
               BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Width" Value="50"/>
        </Style>
    </Window.Resources>

    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left"
                Width="{Binding ElementName=grid,Path=ActualWidth}"
                Grid.IsSharedSizeScope="True">
        <Grid Name="grid" HorizontalAlignment="Left">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c2"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Label Content="Foo:"/>
            <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
            <Label Grid.Row="1" Content="Foobar:"/>
            <TextBox Grid.Row="1" Grid.Column="1"
                     Style="{StaticResource SmallTextBox}"/>
        </Grid>

        <TextBox Grid.Row="1"/>

        <Grid Name="grid2" HorizontalAlignment="Left">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c2"/>
            </Grid.ColumnDefinitions>

            <Label Content="Bar:"/>
            <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
        </Grid>
    </StackPanel>
</Window>

РЕДАКТИРОВАТЬ: Вот решение, основанное на ответе Жюльена Лебосквайна:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="3"/>
        </Style>
        <Style x:Key="SmallTextBox" TargetType="{x:Type TextBox}"
               BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Width" Value="50"/>
        </Style>
    </Window.Resources>

    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left"
                Width="{Binding ElementName=grid,Path=ActualWidth}">
        <Grid Name="grid">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Label Content="Foo:"/>
            <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
            <Label Grid.Row="1" Content="Foobar:"/>
            <TextBox Grid.Row="1" Grid.Column="1"
                     Style="{StaticResource SmallTextBox}"/>
            <TextBox Grid.Row="2" Grid.ColumnSpan="2"/>
            <Label Grid.Row="3" Content="Bar:"/>
            <TextBox Grid.Row="3" Grid.Column="1"
                     Style="{StaticResource SmallTextBox}"/>
        </Grid>
    </StackPanel>
</Window>

Ответы [ 4 ]

1 голос
/ 26 мая 2010

Я думаю, вы поняли это задом наперед. Это не самое большое текстовое поле, которое все портит. Тот факт, что небольшие текстовые поля имеют фиксированный размер, делает их не такими большими, как самые большие. Здесь у вас есть противоречие: использование панели стека, которая означает «принимает ширину моих детей», Width=Auto, которая ведет себя так же, но вы не хотите, чтобы ваша панель стека росла.

Где-то выше в визуальном дереве, вам нужно либо указать ширину, либо использовать элемент управления, размер которого должен занимать все пространство, как Grid.

Лично я пойду с этим решением:

  • Используйте только одну внутреннюю сетку, маленькие текстовые поля не имеют фиксированного размера и большое текстовое поле имеет Grid.ColumnSpan="2".
  • Применить Width="Auto" к первому столбцу и Width="*" ко второму.
  • Замените существующий StackPanel на Grid с первым столбцом фиксированного или звездного размера (чтобы он масштабировался при изменении размера окна). Поместите свою внутреннюю сетку в этот первый столбец.
0 голосов
/ 03 июля 2019

Просто удалите свойства выравнивания:

HorizontalAlignment="Center" VerticalAlignment="Center" 

Например, текстовое поле будет:

<TextBox x:Name="txtMyName1" Margin="3" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox x:Name="txtMyName2" Margin="3" />
0 голосов
/ 26 мая 2010

У меня была бы одна сетка с 4 рядами. И есть ColumnSpan на 3-й строке. Это также означает, что вам не нужны SharedSizeGroups.

<Grid Name="grid" HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Label Content="Foo:"/>
        <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
        <Label Grid.Row="1" Content="Foobar:"/>
        <TextBox Grid.Row="1" Grid.Column="1"
                 Style="{StaticResource SmallTextBox}"/>

        <TextBox Grid.Row="2" Grid.ColumnSpan="2" />

        <Label Content="Bar:"/>
        <TextBox Grid.Row="3" Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
    </Grid>
0 голосов
/ 26 мая 2010
 <TextBox Grid.Row="1" Grid.ColumnSpan="2" /> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...