Подтвердить что ты не робот

WPF: Можно ли установить ширину элемента по процентам?

Скажем, у меня есть 2 кнопки в элементе, и я хочу, чтобы 2 элемента всегда заполняли 1/2 ширины его содержащего элемента каждый, могу ли я сделать это?

UPDATE

почему я не могу сделать что-то вроде

<StackPanel Orientation="Horizontal" Grid.Row="0">
    <Button Content="Click me" Command="{Binding ClickCommand}" Width="1*" />
    <Button Content="Exit" Command="{Binding CloseCommand}" Width="1*" />
</StackPanel>

Почему в этом контексте не работает 1 *? я получаю ошибку

Невозможно преобразовать "1 *"

4b9b3361

Ответ 1

Для этого можно использовать Grid с двумя столбцами.

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="1*"/>
    <ColumnDefinition Width="1*"/>
  </Grid.ColumnDefinitions>

  <Button Grid.Column="0">Button1</Button>
  <Button Grid.Column="1">Button2</Button>
</Grid>

Обратите внимание на использование звезды (*) в свойстве ColumnDefinition.Width. Это означает, что оба столбца занимают одинаковое пространство. Таким образом, в приведенном выше примере каждая кнопка будет занимать 1/2 от доступного пространства содержащего Grid. Поэтому, если вы сделаете один Width равным 2*, этот столбец займет в два раза больше места, чем другой столбец. Надеюсь, это имеет смысл.

Ответ 2

Я создал ContentControl, который позволяет мне обернуть контент, чтобы добавить динамическую процентную ширину/высоту.

/// <summary>
/// This control has a dynamic/percentage width/height
/// </summary>
public class FluentPanel : ContentControl, IValueConverter
{
    #region Dependencie Properties

    public static readonly DependencyProperty WidthPercentageProperty =
        DependencyProperty.Register("WidthPercentage", typeof(int), typeof(FluentPanel), new PropertyMetadata(-1, WidthPercentagePropertyChangedCallback));

    private static void WidthPercentagePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        ((FluentPanel)dependencyObject).OnWidthPercentageChange();
    }

    public int WidthPercentage
    {
        get { return (int)GetValue(WidthPercentageProperty); }
        set { SetValue(WidthPercentageProperty, value); }
    }

    public static readonly DependencyProperty HeightPercentageProperty =
        DependencyProperty.Register("HeightPercentage", typeof(int), typeof(FluentPanel), new PropertyMetadata(-1, HeightPercentagePropertyChangedCallback));

    private static void HeightPercentagePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        ((FluentPanel)dependencyObject).OnHeightPercentageChanged();
    }

    public int HeightPercentage
    {
        get { return (int)GetValue(HeightPercentageProperty); }
        set { SetValue(HeightPercentageProperty, value); }
    }

    #endregion

    #region Methods

    private void OnWidthPercentageChange()
    {
        if (WidthPercentage == -1)
        {
            ClearValue(WidthProperty);
        }
        else
        {
            SetBinding(WidthProperty, new Binding("ActualWidth") { Source = Parent, Converter = this, ConverterParameter = true });
        }
    }

    private void OnHeightPercentageChanged()
    {
        if (HeightPercentage == -1)
        {
            ClearValue(HeightProperty);
        }
        else
        {
            SetBinding(HeightProperty, new Binding("ActualHeight") { Source = Parent, Converter = this, ConverterParameter = false });
        }
    }

    #endregion

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if ((bool)parameter)
        {
            // width
            return (double)value * (WidthPercentage * .01);
        }
        else
        {
            // height
            return (double)value * (HeightPercentage * .01);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}