[wpf] WPF : 너비 및 높이를 백분율 값으로 설정

내가 원하는 말을 TextBlock가지고 그 Width와 같은 그것의 부모 컨테이너의 Width(즉, 좌우로 스트레칭) 또는 그것의 부모 컨테이너의 비율 Width나는이 작업을 수행 할 수있는 방법, XAML절대 값을 지정하지 않고?

부모 컨테이너 컨테이너가 나중에 확장 (확장 Width) 된 경우 하위 요소도 자동으로 확장 되도록이 작업을 수행하고 싶습니다 . (기본적으로 HTML 및 CSS에서와 같이)



답변

부모 컨테이너와 같은 크기로 늘리는 방법은 속성을 사용하는 것입니다.

 <Textbox HorizontalAlignment="Stretch" ...

그러면 Textbox 요소가 가로로 늘어나고 모든 부모 공간을 가로로 채 웁니다 (실제로 사용중인 부모 패널에 따라 다르지만 대부분의 경우 작동합니다).

백분율은 모눈 셀 값에만 사용할 수 있으므로 다른 옵션은 모눈을 만들고 셀 중 하나에 텍스트 상자를 적절한 백분율로 배치하는 것입니다.


답변

텍스트 상자를 그리드 안에 넣어 그리드의 행 또는 열에 백분율 값을 적용하고 텍스트 상자가 부모 셀에 자동으로 채워지도록 할 수 있습니다 (기본적으로). 예:

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


답변

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


답변

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>


답변

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시작하면 높이가 조정되기 시작합니다. 당신은 아마 이것을 해결할 수 StretchUniformToFill.