WPF. Вопрос макета - PullRequest
       9

WPF. Вопрос макета

1 голос
/ 12 октября 2010

парни У меня есть StackPanel. Мне нужно разместить там TextBlock с TextAlignment = TextAlignment.Center [Центр stackPanel] и кнопку на правой стороне с небольшим полем. Как я могу добиться такой раскладки с wpf.

Как добавить кнопку в StackPanel, чтобы мой TextBlock не перемещался из центра.

Ответы [ 3 ]

3 голосов
/ 12 октября 2010

Попробуйте что-то вроде этого:

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

        <TextBox x:Name="txtCentered"
                 Grid.Column="0"
                 Grid.ColumnSpan="2"
                 HorizontalAlignment="Center"
                 VerticalAlignment="Center"
                 Text="Here Is My Text Box" />

        <StackPanel x:Name="stackButtons"
                    Grid.Column="1"
                    Orientation="Vertical"
                    VerticalAlignment="Center">
            <Button x:Name="btnOne" Content="Button One" />
            <Button x:Name="btnTwo" Content="Button Two" />
            <Button x:Name="btnThree" Content="Button Three" />
       </StackPanel>
</Grid>

Обратите внимание, что TextBox охватывает всю сетку (ColumnSpan = "2"), поэтому она будет абсолютно центрирована в сетке (HorizontalAlignment = "Center"). Во втором столбце будет просто StackPanel (или Grid, или UniformGrid, или ...) с кнопками.

ПРИМЕЧАНИЕ. Известным недостатком этого дизайна является то, что кнопки могут перекрывать TextBox, если TextBox достаточно велик, а Grid достаточно мал. Чтобы избежать этого, нужно будет позаботиться и оставить это упражнение для разработчика. Однако этот недостаток будет возникать в любой реализации, где требуется, чтобы TextBox находился в мертвой точке макета.

0 голосов
/ 12 октября 2010

Чтобы избежать потенциального перекрытия между TextBlock и Button, вы можете рассчитать левое поле для Button, которое заканчивается рядом с TextBlock в центре, используя конвертер значений.Тем не менее, мне все еще нравится ответ, предоставленный @Wonko, поскольку он прост и стандартен.

Вот XAML:

<Window x:Class="TextBoxInCenter.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TextBoxInCenter" 
    Title="MainWindow" 
    Height="350" Width="525">
  <Grid>
    <Grid.Resources>
        <local:CustomThicknessValueConverter x:Key="CustomThicknessValueConverter" />
    </Grid.Resources>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBlock 
        x:Name="CenterTextBox"
        Grid.Column="0" 
        Grid.ColumnSpan="2"
        Grid.Row="0"
        Text="Text in Center" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center"
        TextAlignment="Center"/>
    <StackPanel
        Grid.Column="1"
        Grid.Row="0"
        Orientation="Horizontal">
        <Button 
            Margin="{Binding ElementName=CenterTextBox, 
                       Path=ActualWidth, 
                       Converter={StaticResource CustomThicknessValueConverter}}"
            Height="23"
            Content="Click me 1">
        </Button>
        <Button 
            Height="23"
            Content="Click me 2">
        </Button>
    </StackPanel>
  </Grid>
</Window>

Вот конвертер значений:

using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;

namespace TextBoxInCenter
{
  public class CustomThicknessValueConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      Debug.WriteLine("Convert");

      Thickness thickness = new Thickness(0, 0, 0, 0);

      if ( value != null )
      {
         double actaulwidth = (double)value;
         thickness.Left = actaulwidth/2;
      }

      return thickness;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }
}
0 голосов
/ 12 октября 2010

Как насчет чего-то вроде:

<StackPanel>
    <Grid HorizontalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="MyTextBlock" TextAlignment="Center"/>
        <Button HorizontalAlignment="Right" Grid.Column="1">MyButton</Button>
    </Grid>
</StackPanel>

РЕДАКТИРОВАТЬ:

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

<StackPanel>
        <Grid HorizontalAlignment="Stretch">
            <TextBlock Text="MyTextBlock" TextAlignment="Center"/>
            <Button HorizontalAlignment="Right">MyButton</Button>
        </Grid>
    </StackPanel>
...