说我想要一个TextBlock
有它Width
等于它的父容器的Width
(也就是说,从一边到另一边拉伸)或它的父容器的百分比Width
,我怎么能在做到这一点XAML
,而无需指定绝对值?
我想这样做,以便如果稍后将“父容器”容器展开(Width
增加),其“子元素”也将自动展开。(基本上,就像在HTML和CSS中一样)
说我想要一个TextBlock
有它Width
等于它的父容器的Width
(也就是说,从一边到另一边拉伸)或它的父容器的百分比Width
,我怎么能在做到这一点XAML
,而无需指定绝对值?
我想这样做,以便如果稍后将“父容器”容器展开(Width
增加),其“子元素”也将自动展开。(基本上,就像在HTML和CSS中一样)
Answers:
您可以将文本框放在网格内,以在网格的行或列上执行百分比值,并让文本框自动填充到其父单元格(默认情况下会填充)。例:
<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。
通常,您将使用适合您的方案的内置布局控件(例如,如果要相对于父级缩放,请使用网格作为父级)。如果要使用任意父元素来执行此操作,可以创建一个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%:
<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>
CultureInfo.InvariantCulture
双重转换,因为在不同的文化中,“与” parameter
被视为string
和,decimal separator
将无法按预期工作。
对于任何遇到错误的人,例如:'2 *'字符串都不能转换为Length。
<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>
<RowDefinition Height="auto" />
呢?
可以使用IValueConverter实现。从IValueConverter继承的Converter类采用一些参数,例如value
(百分比)和parameter
(父母的宽度),并返回所需的宽度值。在XAML文件中,组件的宽度使用所需的值进行设置:
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>
我知道它不是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%),并在需要时延伸。
我使用两种方法进行相对大小调整。我有一类叫做Relative
有三个附加属性To
,WidthPercent
并且HeightPercent
如果我想要一个元素是在视觉树元素的任何地方的相对大小是有用的,比转换器的做法感觉少哈克-尽管使用你的作品,你很高兴。
另一种方法更狡猾。在ViewBox
其中要添加相对大小的位置添加一个,然后在其中添加Grid
宽度为100的值。然后,如果在其中添加TextBlock
宽度为10的值,则显然是100的10%。
该ViewBox
会的规模Grid
根据任何空间,它已被赋予,所以如果其页面上的唯一的事情,那么Grid
将被缩小了全宽和有效的,你TextBlock
缩放页面的10%。
如果您未在上设置高度,Grid
则它会缩小以适合其内容,因此它们的尺寸都相对较大。您必须确保内容不会太高,即开始更改给定空间的宽高比,ViewBox
否则将开始缩放高度。您可以使用来解决此Stretch
问题UniformToFill
。