将Horizo​​ntalAlignment设置为Stretch和Left的TextBox

时间:2012-10-23 20:59:56

标签: .net wpf xaml alignment

注意:我读过这个问题及其答案:HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time?。他们都没有做我想要的。


我有以下xaml:

<Grid ShowGridLines="True" x:Name="_testGrid" Height="30" >
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"></ColumnDefinition>
    <ColumnDefinition Width="*"></ColumnDefinition>
    <ColumnDefinition Width="*"></ColumnDefinition>
  </Grid.ColumnDefinitions>

  <TextBox Text="Text 1" HorizontalAlignment="Stretch"
          MaxWidth="75" Margin="5"/>
  <TextBox Grid.Column="1" Text="Text 2" Margin="5"                 
       HorizontalAlignment="Stretch" MaxWidth="130"/>
  <TextBox Grid.Column="2"  Text="Text 3" Margin="5"               
       HorizontalAlignment="Stretch" MaxWidth="100"/>
</Grid>

它产生了这个:

Three Text Boxes Centered in their columns

此设置具有很大的调整大小支持。如果窗口缩小,那么TextBoxes也会收缩。

唯一的问题是我需要将它们左对齐:

Show where I want the textboxes

我看到的所有解决方案最终都会破坏文本框的一部分(而不是缩小它)。

我正在寻找WPF的可能性吗?

3 个答案:

答案 0 :(得分:4)

找到答案here

它仅适用于网格。这是更新的xaml:

<Grid ShowGridLines="True" x:Name="_testGrid" Height="30" >
  <Grid.ColumnDefinitions>
    <ColumnDefinition MaxWidth="75" Width="*"/>
    <ColumnDefinition Width="0.01*" />
    <ColumnDefinition MaxWidth="130" Width="*"/>
    <ColumnDefinition Width="0.01*" />
    <ColumnDefinition MaxWidth="100" Width="*"/>
    <ColumnDefinition Width="0.01*" />
  </Grid.ColumnDefinitions>

  <TextBox Grid.Column="0" Text="Text 1" Margin="5"/>
  <TextBox Grid.Column="2" Text="Text 2" Margin="5"  />
  <TextBox Grid.Column="4" Text="Text 3" Margin="5" />
</Grid>

答案 1 :(得分:2)

您也可以将TextBox放在专门的Panel中,如下所示:

public class LeftStretchPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        foreach (UIElement element in InternalChildren)
        {
            element.Measure(availableSize);
        }

        return new Size();
    }

    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        foreach (UIElement element in InternalChildren)
        {
            double width = arrangeBounds.Width;
            FrameworkElement fwElement = element as FrameworkElement;

            if (fwElement != null && width > fwElement.MaxWidth)
            {
                width = fwElement.MaxWidth;
            }

            element.Arrange(new Rect(0, 0, width, arrangeBounds.Height));
        }

        return arrangeBounds;
    }
}

您的XAML将如下所示:

<Grid ShowGridLines="True" Height="30">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <local:LeftStretchPanel Grid.Column="0" Margin="5">
        <TextBox Text="Text 1" MaxWidth="75"/>
    </local:LeftStretchPanel>
    <local:LeftStretchPanel Grid.Column="1" Margin="5">
        <TextBox Text="Text 2" MaxWidth="130"/>
    </local:LeftStretchPanel>
    <local:LeftStretchPanel Grid.Column="2" Margin="5">
        <TextBox Text="Text 3" MaxWidth="100"/>
    </local:LeftStretchPanel>
</Grid>

答案 2 :(得分:0)

你在做什么实际上非常复杂。

你真的希望它保持对齐。这很容易。将其设置为Horizo​​ntalAlignment =“Left”。

您需要最小尺寸和最大尺寸,并且能够在调整窗口大小时在这些尺寸之间增长。

首先,你需要TextBox在它和Column之间有一个父级,它将扩展到Column的整个宽度。

<Window x:Class="TestTextAlignment.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:loc="clr-namespace:TestTextAlignment"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid Name="MainGrid" ShowGridLines="True" Height="30" >
        <Grid.Resources>
            <loc:ColumnSizeToTextBoxSizeConverter x:Key="SizeConverter" LeftMargin="5" RightMargin="25"/>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Name="ColDef1" Width="*"></ColumnDefinition>
            <ColumnDefinition Name="ColDef2" Width="*"></ColumnDefinition>
            <ColumnDefinition Name="ColDef3" Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <DockPanel Name="Col1">
            <TextBox Text="Text 1" Margin="5" HorizontalAlignment="Left" MinWidth="100" MaxWidth="300" 
                     Width="{Binding ElementName=Col1, Path=ActualWidth, Mode=OneWay, Converter={StaticResource SizeConverter}}" />
        </DockPanel>
        <DockPanel Name="Col2" Grid.Column="1">
            <TextBox Text="Text 2" Margin="5" HorizontalAlignment="Left" MinWidth="100" MaxWidth="300"  
                     Width="{Binding ElementName=Col2, Path=ActualWidth, Mode=OneWay, Converter={StaticResource SizeConverter}}" />
        </DockPanel>
        <DockPanel Name="Col3" Grid.Column="2" >
            <TextBox Text="Text 3" Margin="5" HorizontalAlignment="Left" MinWidth="100" MaxWidth="300"  
                     Width="{Binding ElementName=Col3, Path=ActualWidth, Mode=OneWay, Converter={StaticResource SizeConverter}}" />
        </DockPanel>
    </Grid>
</Window>

然后正如您在XAML中看到的那样,您需要一个转换器,它将TextBox大小设置为父对象减去左右边距。

using System;
using System.Windows.Data;

namespace TestTextAlignment
{
    public class ColumnSizeToTextBoxSizeConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (double)value - LeftMargin - RightMargin;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion

        public double LeftMargin { get; set; }
        public double RightMargin { get; set; }
    }
}

注意:您可以增强转换器以将左右边距作为转换参数,因此可以使用一个转换器向任何元素发送不同的大小。