开发者

WPF. Layout issue

guys I have StackPanel. I need place there TextBlock with TextAlignment = TextAlignment.Center[Center of stackPanel] and button at right side with small margin. How can开发者_开发技巧 I achieve such layout with wpf.

How can I add button to StackPanel, that my TextBlock doesn't move from center.


Try something like this:

<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>

Notice that the TextBox spans the entire Grid (ColumnSpan="2"), so that it will be absolutely centered in the Grid (HorizontalAlignment="Center"). The second column will just have a StackPanel (or Grid, or UniformGrid, or...) with the buttons.

NOTE: The known drawback of this design is that the buttons could overlap the TextBox if the TextBox is big enough and the Grid is small enough. Care will have to be taken to avoid this, and is left as an exercise for the developer. However, this drawback will occur on any implementation where the requirement is that the TextBox is dead-center of the layout.


How about something like:

<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>

EDIT:

If you want the textblock to be in the center of the grid, you can just remove the ColumnDefinitions above. However, note that if the Grid becomes small enough here, the button will overlap with the TextBlock.

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


To avoid potential overlap between the TextBlock and Button, you can calculate the left margin for the Button that ends up next to the TextBlock in the center using a Value Converter. That said I still like answer provided by @Wonko as it is simple and standard.

Here is the 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>

Here is the Value Converter:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜