Как мне привязать ширину ColumnDefinition или высоту RowDefinition? - PullRequest
33 голосов
/ 29 сентября 2008

В шаблоне View-Model-ViewModel для WPF я пытаюсь привязать данные высоты и ширины различных определений для элементов управления сеткой, чтобы я мог сохранить значения, которые пользователь устанавливает для них после использования GridSplitter. Однако нормальный шаблон, похоже, не работает для этих конкретных свойств.

Примечание. Я публикую это как справочный вопрос, который я публикую, так как Google подвел меня, и я должен был решить это сам. Мой собственный ответ следовать.

Ответы [ 4 ]

39 голосов
/ 09 сентября 2011

Создайте IValueConverter следующим образом:

public class GridLengthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double val = (double)value;
        GridLength gridLength = new GridLength(val);

        return gridLength;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        GridLength val = (GridLength)value;

        return val.Value;
    }
}

Затем вы можете использовать конвертер в вашем Binding:

<UserControl.Resources>
    <local:GridLengthConverter x:Key="gridLengthConverter" />
</UserControl.Resources>
...
<ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
                                  Mode=TwoWay,
                                  Converter={StaticResource gridLengthConverter}}" />
20 голосов
/ 29 сентября 2008

Я обнаружил несколько ошибок:

  1. Хотя в XAML это может выглядеть как двойное, фактическое значение для * Definition's Height или Width - это структура 'GridLength'.
  2. Все свойства GridLength доступны только для чтения, вы должны создавать новое каждый раз, когда изменяете его.
  3. В отличие от любого другого свойства в WPF, ширина и высота не устанавливают режим привязки данных по умолчанию на «TwoWay», вы должны установить это вручную.

Таким образом, я использовал следующий код:

private GridLength myHorizontalInputRegionSize = new GridLength(0, GridUnitType.Auto)
public GridLength HorizontalInputRegionSize
{
    get
    {
        // If not yet set, get the starting value from the DataModel
        if (myHorizontalInputRegionSize.IsAuto)
            myHorizontalInputRegionSize = new GridLength(ConnectionTabDefaultUIOptions.HorizontalInputRegionSize, GridUnitType.Pixel);
        return myHorizontalInputRegionSize;
    }
    set
    {
        myHorizontalInputRegionSize = value;
        if (ConnectionTabDefaultUIOptions.HorizontalInputRegionSize != myHorizontalInputRegionSize.Value)
        {
            // Set the value in the DataModel
            ConnectionTabDefaultUIOptions.HorizontalInputRegionSize = value.Value;
        }
        OnPropertyChanged("HorizontalInputRegionSize");
    }
}

И XAML:

<Grid.RowDefinitions>
    <RowDefinition Height="*" MinHeight="100" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" />
</Grid.RowDefinitions>
4 голосов
/ 06 мая 2015

Самое простое решение - просто использовать строковые настройки для этих свойств, чтобы WPF автоматически поддерживал их с помощью GridLengthConverter без какой-либо дополнительной работы.

4 голосов
/ 30 сентября 2008

Другая возможность, поскольку вы начали преобразование между GridLength и int, - это создать IValueConverter и использовать его при привязке к Width. IValueConverter s также обрабатывают двустороннее связывание, потому что они имеют методы ConvertTo() и ConvertBack().

...