我有一个非常简单的窗口,其中一个Grid包含两列,一个TextBlock和一个TextBox。
我需要将第0列设置为自动调整其内容大小,并使第1列(内容)为第0列大小的4倍。
我该怎么做?如果这是解决方案,我将创建一个Grid后代,因为我真的需要这个功能。
修改:更多解释。第0列的内容不会在运行时更改,因此第0列或第1列的大小在运行时不得更改。网格将是配置有SizeToContent="WidthAndHeight"
的窗口的子节点,因此不存在额外的空间。
回答德米特里:我用下面的代码尝试了你说的话,它根本不起作用:
<Window x:Class="UnderstandSizing.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
SizeToContent="WidthAndHeight" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*" />
<ColumnDefinition Width=".75*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="THIS IS THE LABEL:" />
<TextBox Grid.Column="1" Text="content" />
</Grid>
</Window>
最后编辑:为什么我(或任何人)需要这个?
WPF的一个好处是它无法在没有固定尺寸的情况下工作吗?如果你有缺陷并且你有更大的字体大小,一切都会好看。如果您将UI翻译成另一种需要x2大小的语言,一切都会好起来的。如果你有不同的PPI设置,一切都会好起来的。
但我不想看到的是屏幕在运行时改变其大小,因为用户不习惯这样做。这就是为什么我想将输入字段的大小设置为知道字段的倍数的原因。如果我让标签单元格重新调整到需要的大小,然后我将内容单元格设置为标签的乘数,我将获得自动调整的好处,以及用户期望具有固定大小屏幕的行为(除非他们更改调整大小它)。
答案 0 :(得分:6)
您可以在网格列上使用绑定:
<Grid.ColumnDefinitions>
<ColmunDefinition Width="Auto" x:Name="firstCol"/>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=firstCol, Converter={StaticResource MultiplyConverter}, ConverterParameter=4}" />
</Grid.ColumnDefinitions>
然后是转换器:
public class MultiplyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double originalValue;
double multiplier;
if (value != null && parameter != null &&
double.TryParse(value.ToString(), out originalValue) &&
double.TryParse(parameter.ToString(), out multiplier)) //Can be lots of things: sentinel object, NaN (not a number)...
{
return originalValue * multiplier;
}
else return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
您也可以为网格列编写附加属性。
答案 1 :(得分:0)
取自:http://www.tanguay.info/web/index.php?pg=codeExamples&id=36
这个想法是使用:
更新2 - 发布了完整的XAML(请注意网格子项的行为):
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*" />
<ColumnDefinition Width=".75*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Background="Yellow" Grid.Column="0">
<TextBlock Text="THIS IS THE LABEL:" />
</Grid>
<Grid Background="Blue" Grid.Column="1">
<TextBox Background="Transparent" Text="content" />
</Grid>
</Grid>
</Grid>
</Window>
我刚检查过它并且有效。
更新:简单地说 - 在WPF中没有开箱即用的方法。根据您的情况,您必须提出一些技巧来使您的电网工作。
另一个问题是 - 通常WPF布局被设计为保护性的,即如果你的网格的孩子不能缩小 - 通常你的布局逻辑应该适应它,通常是通过暂停一些布局规则。
答案 2 :(得分:0)
修改强>
如果在编译时已知大小,手动设置宽度会不会更容易?
你可以使用BindingConverter,我会在水平StackPanel中使用单独的项目(看看StackPanel的宽度对于你的内容来说足够大):
这是清理后的代码。
MainWindow.xaml:
<!-- define xmlns:local="clr-namespace:YourAppNamespace" -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<StackPanel.Resources>
<local:WidthConverter x:Key="wc" />
</StackPanel.Resources>
<Grid Background="Gray" x:Name="col1">
<TextBlock Text="blub"/>
</Grid>
<Grid Background="Orange" Width="{Binding ElementName=col1, Path=ActualWidth, Converter={StaticResource ResourceKey=wc}}">
<Label Content="bla"></Label>
</Grid>
</StackPanel>
MainWindow.xaml.cs:
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is double))
{
return Binding.DoNothing;
}
return ((double)value) * 4.0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
答案 3 :(得分:0)
据我所知,您正在尝试布局标签(文本块)及其相应的输入字段。作为一个指标,你应该首先看到Beth Massi's
Windows Client
video关于开发data entry
表单的简单数据输入表格,但是也很好地展示了布局。
特别注意她如何使用设计器,属性窗口和XAML
来设置WPF窗口上的控件,然后我认为您不应该需要第一列为Auto
4*
第一列的大小和第二列。
编辑:根据相关更新,我发布了一个可能的解决方案,如下所示:
XAML文件代码(注意SizeToContent
中的Window
用法以及绑定到ActualWidth
Textbox
控件的<Window x:Class="GridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:GridTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
d:DesignHeight="350"
d:DesignWidth="525"
SizeToContent="WidthAndHeight"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<local:FourWidthConverter x:Key="FourWidthConv" />
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="tb"
Grid.Column="0"
Text="Auto Text, change at design time to see changes in Width" />
<TextBox Name="tx"
Grid.Column="1"
Width="{Binding ElementName=tb,
Path=ActualWidth,
Converter={StaticResource FourWidthConv}}"
Text="4 * col 1 width displaying Text in SizetoContentWindow" />
</Grid>
</Window>
属性:
.Xaml.cs
using System.Windows;
using System.Windows.Data;
namespace GridTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class FourWidthConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return 4 * (double)value;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
}
文件代码(请注意转换器):
{{1}}