WPF:将宽度(和高度)设置为百分比值

说我想要一个TextBlockWidth等于它的父容器的Width (即从一边延伸到另一边)或它的父容器Width的百分比,我怎么能在XAML完成这个没有指定绝对值?

我想这样做,所以如果父容器容器稍后展开(其“ Width增加”),其“子元素”也将自动扩展。 (基本上,就像在HTML和CSS)

将其拉伸到与父容器大小相同的方式是使用属性:

  <Textbox HorizontalAlignment="Stretch" ... 

这将使文本框元素水平拉伸,并水平填充所有的父空间(实际上它取决于你正在使用的父面板,但应该适用于大多数情况下)。

百分比只能与网格单元格值一起使用,所以另一种select是创build网格并将文本框放入其中一个具有适当百分比的单元格中。

这是我以前从09年发布的更新的答案,其中包含不正确的信息。 下面的例子应该certificate更好:

您可以将文本框放在网格中,以在网格的行或列上执行百分比值,并让文本框自动填充到其父级单元格(因为它们将默认为默认值)。 例:

 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="2*" /> <ColumnDefinition Width="3*" /> </Grid.ColumnDefinitions> <TextBox Grid.Column="0" /> <TextBox Grid.Column="1" /> </Grid> 

这将使#1 2/5的宽度,#2 3/5。

原始post中有不正确的/不完整的信息

不要以为你可以做%,但你可以做* 🙂

例:

 <TextBox width="2*"/> <TextBox width="3*"/> 

这将使#1 2/5的宽度,#2 3/5。

通常情况下,您将使用适合您的scheme的内置布局控件(例如,如果要相对于父级缩放,则使用网格作为父级)。 如果你想用一个任意的父元素来实现,你可以创build一个ValueConverter来实现,但是它可能不会像你想的那么干净。 但是,如果你绝对需要它,你可以做这样的事情:

 public class PercentageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

可以像这样使用,以获得一个子文本框的10%的父级canvas的宽度:

 <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300"> <Window.Resources> <local:PercentageConverter x:Key="PercentageConverter"/> </Window.Resources> <Canvas x:Name="canvas"> <TextBlock Text="Hello" Background="Red" Width="{Binding Converter={StaticResource PercentageConverter}, ElementName=canvas, Path=ActualWidth, ConverterParameter=0.1}"/> </Canvas> </Window> 

对于任何遇到错误的人: '2 *'string不能转换为长度。

 <Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="2*" /><!--This will make any control in this column of grid take 2/5 of total width--> <ColumnDefinition Width="3*" /><!--This will make any control in this column of grid take 3/5 of total width--> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition MinHeight="30" /> </Grid.RowDefinitions> <TextBlock Grid.Column="0" Grid.Row="0">Your text block a:</TextBlock> <TextBlock Grid.Column="1" Grid.Row="0">Your text block b:</TextBlock> </Grid> 

我使用两种方法进行相对大小调整。 我有一个叫做Relative的类,有三个附加的属性ToWidthPercentHeightPercent ,如果我想让一个元素成为视觉树中任何一个元素的相对大小,并且感觉比转换器的方法更简单,你,你很高兴。

另一种方法更狡猾。 添加一个你想要的相对大小的ViewBox ,然后在里面,添加一个宽度为100的Grid 。然后,如果你添加一个宽度为10的TextBlock ,那显然是100的10%。

ViewBox将根据给定的空间来缩放Grid ,所以如果它是网页上唯一的东西,那么Grid将会被全部缩放并且有效,你的TextBlock被缩放到页面的10%。

如果你没有在Grid上设置高度,那么它会缩小以适应它的内容,所以它会相对较大。 你必须确保内容不会太高,即开始改变ViewBox的空间宽高比,否则它将开始缩放高度。 你可以用Stretch of UniformToFill解决这个UniformToFill

我知道这不是Xaml,但我做了与文本框的SizeChanged事件相同的事情:

 private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e) { TextBlock textBlock = sender as TextBlock; FrameworkElement element = textBlock.Parent as FrameworkElement; textBlock.Margin = new Thickness(0, 0, (element.ActualWidth / 100) * 20, 0); } 

该文本框似乎是它的父母的80%大小(很好的边缘是20%),并在需要的时候伸展。

ConverterClass:

 public class SizePercentageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (parameter == null) return 0.7 * value.ToDouble(); string[] split = parameter.ToString().Split('.'); double parameterDouble = split[0].ToDouble() + split[1].ToDouble() / (Math.Pow(10, split[1].Length)); return value.ToDouble() * parameterDouble; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // Don't need to implement this return null; } } 

XAML:

 <UserControl.Resources> <m:SizePercentageConverter x:Key="PercentageConverter" /> </UserControl.Resources> <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Width="{Binding Converter={StaticResource PercentageConverter}, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualWidth}" Height="{Binding Converter={StaticResource PercentageConverter}, ConverterParameter=0.6, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualHeight}"> .... </ScrollViewer>