WPF:将宽度(和高度)设置为百分比值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/717299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF: Setting the Width (and Height) as a Percentage Value
提问by Andreas Grech
Say I want a TextBlock
to have its Width
equal to it's Parent container's Width
(ie, stretch from side to side) or a percentage of it's Parent Container Width
, how can I accomplish this in XAML
without specifying absolute values?
说我想要一个TextBlock
有它Width
等于它的父容器的Width
(即,从一边到另一边拉伸)或它的父容器的百分比Width
,我怎么能在做到这一点XAML
,而无需指定绝对值?
I want to do this so that if the Parent Container container is later on expanded (its' Width
increased), its' Child Elements will also be expanded automatically. (basically, like in HTML and CSS)
我想这样做,以便如果父容器容器稍后扩展(它的'Width
增加),它的'子元素也将自动扩展。(基本上,就像在 HTML 和 CSS 中一样)
采纳答案by gcores
The way to stretch it to the same size as the parent container is to use the attribute:
将其拉伸到与父容器相同大小的方法是使用属性:
<Textbox HorizontalAlignment="Stretch" ...
That will make the Textbox element stretch horizontally and fill all the parent space horizontally (actually it depends on the parent panel you're using but should work for most cases).
这将使 Textbox 元素水平拉伸并水平填充所有父空间(实际上这取决于您使用的父面板,但应该适用于大多数情况)。
Percentages can only be used with grid cell values so another option is to create a grid and put your textbox in one of the cells with the appropriate percentage.
百分比只能与网格单元格值一起使用,因此另一种选择是创建一个网格并将文本框放入具有适当百分比的单元格之一。
回答by cwap
You can put the textboxes inside a grid to do percentage values on the rows or columns of the grid and let the textboxes auto-fill to their parent cells (as they will by default). Example:
您可以将文本框放在网格内以在网格的行或列上设置百分比值,并让文本框自动填充到其父单元格(默认情况下)。例子:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" />
<TextBox Grid.Column="1" />
</Grid>
This will make #1 2/5 of the width, and #2 3/5.
这将使宽度的 #1 2/5 和 #2 3/5。
回答by kvb
Typically, you'd use a built-in layout control appropriate for your scenario (e.g. use a grid as a parent if you want scaling relative to the parent). If you want to do it with an arbitrary parent element, you can create a ValueConverter do it, but it probably won't be quite as clean as you'd like. However, if you absolutely need it, you could do something like this:
通常,您会使用适合您的场景的内置布局控件(例如,如果您想相对于父级进行缩放,则使用网格作为父级)。如果你想用任意的父元素来做,你可以创建一个 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();
}
}
Which can be used like this, to get a child textbox 10% of the width of its parent canvas:
可以这样使用,以获取其父画布宽度的 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>
回答by Zain Ali
For anybody who is getting an error like : '2*' string cannot be converted to Length.
对于任何收到类似错误的人:'2*' 字符串无法转换为长度。
<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>
回答by Adem Catamak
IValueConverter implementation can be used. Converter class which take inheritance from IValueConverter take some parameters like value
(percentage) and parameter
(parent's width) and returns desired width value. In XAML file, component's width is set with that desired with value:
可以使用 IValueConverter 实现。从 IValueConverter 继承的转换器类采用一些参数,如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:
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>
回答by Luke Puplett
I use two methods for relative sizing. I have a class called Relative
with three attached properties To
, WidthPercent
and HeightPercent
which is useful if I want an element to be a relative size of an element anywhere in the visual tree and feels less hacky than the converter approach - although use what works for you, that you're happy with.
我使用两种方法进行相对大小调整。我有一类叫做Relative
有三个附加属性To
,WidthPercent
并且HeightPercent
如果我想要一个元素是在视觉树元素的任何地方的相对大小是有用的,比转换器的做法感觉少哈克-尽管使用你的作品,你很满意。
The other approach is rather more cunning. Add a ViewBox
where you want relative sizes inside, then inside that, add a Grid
at width 100. Then if you add a TextBlock
with width 10 inside that, it is obviously 10% of 100.
另一种方法比较狡猾。ViewBox
在里面添加一个你想要相对尺寸的地方,然后在里面,Grid
在宽度为 100 处添加一个。然后如果你在TextBlock
里面添加一个宽度为 10 的,它显然是 100 的 10%。
The ViewBox
will scale the Grid
according to whatever space it has been given, so if its the only thing on the page, then the Grid
will be scaled out full width and effectively, your TextBlock
is scaled to 10% of the page.
该ViewBox
会的规模Grid
根据任何空间,它已被赋予,所以如果其页面上的唯一的事情,那么Grid
将被缩小了全宽和有效的,你TextBlock
缩放页面的10%。
If you don't set a height on the Grid
then it will shrink to fit its content, so it'll all be relatively sized. You'll have to ensure that the content doesn't get too tall, i.e. starts changing the aspect ratio of the space given to the ViewBox
else it will start scaling the height as well. You can probably work around this with a Stretch
of UniformToFill
.
如果你没有在 上设置高度,Grid
那么它会缩小以适应它的内容,所以它都会相对变大。您必须确保内容不会太高,即开始更改给定空间的纵横比,ViewBox
否则它也将开始缩放高度。您可能可以使用Stretch
of解决此问题UniformToFill
。
回答by Crippeoblade
I know it's not Xaml but I did the same thing with SizeChanged event of the textbox:
我知道它不是 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);
}
The textbox appears to be 80% size of it's parent (well right side margin is 20%) and stretches when needed.
文本框似乎是其父级的 80% 大小(右侧边距为 20%)并在需要时拉伸。