Как привязать к данным ширину ColumnDefinition или высоту RowDefinition?

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

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
34
0
33 268
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Я обнаружил ряд ошибок:

  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>

GridLength специфичен для WPF, поэтому не относится к уровню ViewModel.

Greg Sansom 09.09.2011 11:33

Я думаю, что вера «нет WPF в ViewModel» неверна, поскольку WPF имеет множество конструкций, относящихся к шаблону MVVM, например, саму привязку данных. Вместо этого вы могли бы сказать «GridLength специфична для ВИДА» (если только это не является частью проблемы предметной области, например, в приложениях визуализации данных, чьей целью является компоновка и отображение вещей). Но уверен, что это спорный ...

heltonbiker 17.01.2014 22:24

@heltonbiker "GridLength относится к ВИДУ" является более точным. если ваша бизнес-логика полностью или частично не связана с макетом (дизайном) пользовательского интерфейса.

Ahmed Alejo 24.11.2015 15:27

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

Создайте 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;
    }
}

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

<UserControl.Resources>
    <local:GridLengthConverter x:Key = "gridLengthConverter" />
</UserControl.Resources>
...
<ColumnDefinition Width = "{Binding Path=LeftPanelWidth, 
                                  Mode=TwoWay,
                                  Converter = {StaticResource gridLengthConverter}}" />

Если вы ищете решение очень похожей проблемы, вы можете найти его здесь: stackoverflow.com/questions/7660967/…

dzendras 04.01.2014 22:24

В Wpf уже есть класс GridLengthConverter. Можно ли было бы использовать его как есть?

heltonbiker 17.01.2014 22:53

@heltonbiker К сожалению, GridLengthConverter реализует ITypeConverter, а не IValueConverter, и поэтому не может использоваться в качестве преобразования привязки WPF.

Tim Sylvester 11.07.2014 04:55

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

Другие вопросы по теме