3

我有一个非常简单的窗口,它的网格包含两列,一个 TextBlock 和一个 TextBox。

在此处输入图像描述

我需要它来将第 0 列设置为自动调整其内容的大小,并使第 1 列(内容)的大小是第 0 列大小的 4 倍。

我怎样才能做到这一点。如果这是解决方案,我将创建一个 Grid 后代,因为我真的需要这个功能。

编辑:更多解释。第 0 列的内容在运行时不会改变,因此第 0 列或第 1 列的大小不能在运行时改变。网格将是配置的窗口的子窗口,SizeToContent="WidthAndHeight"因此不得存在额外空间。

对 Dmitry 的回答:我用下面的代码尝试了你所说的,但它根本不起作用:

<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 设置,一切都会很好。

但是我不想看到屏幕在运行时改变它的大小,因为用户不习惯这个。这就是为什么我想将输入字段的大小设置为已知字段的倍数。如果我让标签单元格重新调整大小到它需要的大小,然后我将内容单元格设置为标签的乘数,我将获得自动调整大小的好处,用户期望具有固定大小的屏幕(除非他们改变它调整大小它)。

4

4 回答 4

7

您可以在网格列上使用绑定:

<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();
    }
}

您也可以为网格列编写附加属性。

于 2012-01-25T11:16:53.190 回答
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 布局被设计成保护性的,即如果你的网格的子不能被缩小——通常你的布局逻辑应该适应它,通常是通过暂停一些布局规则。

于 2012-01-25T11:03:07.757 回答
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();
    }
}
于 2012-01-25T11:13:47.633 回答
0

据我了解,您正在尝试为其布局标签(文本块)和相应的输入字段。作为一个指标,您应该首先看到关于简单数据输入表单的Beth Massi's Windows Client视频,该视频正在开发一个data entry表单,但也很好地展示了布局。

特别观察她如何使用设计器、属性窗口和 来布置 WPF 窗口上的控件XAML,然后我认为您不需要第一列的Auto大小和第一列的4*第二列。

编辑:根据有问题的更新,我发布了一个可能的解决方案,如下所示:

  1. 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>
    
  2. .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();
            }
        }
    }
    
于 2012-01-25T11:49:38.647 回答