WPF:幅(および高さ)をパーセント値として設定する


149

私が欲しいと言っTextBlock持っているそのWidthに等しく、それの親コンテナのWidth(すなわち、左右にストレッチ)、またはそれの親コンテナの割合Width私はこれを達成することができますどのように、XAML絶対値を指定せず?

これを実行して、親コンテナーコンテナーが後で展開された(Width増加した)場合に、その子要素も自動的に展開されるようにします。(基本的に、HTMLやCSSのように)


この答えを見てください。
Jesper Fyhr Knudsen

cwapの回答を使用し、tbをグリッドの設定に含めて、その配置をストレッチします。
Shimmy Weitzhandler、2010年

回答:


90

親コンテナと同じサイズに拡大する方法は、属性を使用することです:

 <Textbox HorizontalAlignment="Stretch" ...

これにより、Textbox要素が水平方向に引き伸ばされ、すべての親スペースが水平方向に塗りつぶされます(実際には、使用している親パネルによって異なりますが、ほとんどの場合は機能するはずです)。

パーセンテージはグリッドセル値でのみ使用できるため、別のオプションはグリッドを作成し、適切なパーセンテージでセルの1つにテキストボックスを配置することです。


221

グリッド内にテキストボックスを配置して、グリッドの行または列にパーセント値を設定し、テキストボックスを親セルに自動入力できます(デフォルトのように)。例:

<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になります。


7
すでに試してみましたが、次のエラーが発生します。「2 *」文字列は長さに変換できません。」
Andreas Grech、

6
実際、*(アスタリスク)は小さな星です;)etymonline.com/index.php?term=asterisk
Pratik Deoghare

73
私のお母さんは私がスターだと言っています
Denys Wessels 2014年

7
TextBoxがグリッド内にある場合でも、これは機能しません。幅は、Double、Qualified Double(double値の後にpx、in、cmまたはptが続く)、またはAutoに設定できます。msdn.microsoft.com/en-GB/library/…を
Darren

2
はい..これは実際には非常に貧弱な回答ですが、すべての賛成票に基づいて、誰かを助けたと思います(かなり前のことです)。そのため、私はそれを削除していません。
cwap 2014年

58

通常、シナリオに適した組み込みのレイアウトコントロールを使用します(たとえば、親に対して相対的にスケーリングする場合は、グリッドを親として使用します)。任意の親要素でそれを実行したい場合は、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>

これは本当にクールです、コードでどうすればできますか(テキストボックスの幅を設定します)?
ジェレミー

9
はと見なされ、異なるカルチャでは期待どおりに機能しないCultureInfo.InvariantCultureため、二重変換に追加することを検討する必要があります。parameterstringdecimal separator
フラットエリック

33

次のようなエラーが発生している場合:'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>

なんで<RowDefinition Height="auto" />
ベン・

2
"auto"は、コントロールが必要とするだけのスペースを取ります
Yama

どうもありがとう、これが一番の答えになるはずです。
マフィイ2016年

これは間違いなく最良の答えです。
Knut Valen

7

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:

<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>

4

私はそれが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%です)、必要に応じて拡大されます。


4

相対サイズ設定には2つの方法を使用します。私はと呼ばれるクラス持っているRelative3つの添付プロパティではToWidthPercentHeightPercent私は要素がビジュアルツリー内の要素の任意の場所の相対的な大きさになりたい場合に便利ですし、コンバータのアプローチよりも少ないハック感じている-ただし、あなたことを、あなたのために働くものを使用満足しています。

他のアプローチはかなり狡猾です。ViewBox内に相対サイズが必要な場所を追加してから、その中Gridに幅100のaを追加します。次に、TextBlockを、幅10のをと、それは明らかに100の10%になります。

ViewBox拡大縮小されますGridので、ページ上の唯一のことは、その後場合は、それが与えられているものは何でもスペースに応じてGrid、効果的にスケールアウトされる全幅をして、TextBlockページの10%に縮小されます。

に高さを設定しない場合Grid、コンテンツに合わせて縮小されるため、すべて相対的にサイズが調整されます。コンテンツが高すぎないことを確認する必要があります。つまり、指定されたスペースのアスペクト比を変更しViewBox始めます。そうしないと、高さもスケーリングされます。あなたは、おそらくでこれを回避することができますStretchUniformToFill

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.