Привязка WPF OneWay работает только один раз

У меня есть представление с двумя выпадающими списками. В одном пользователь выбирает имя типа трассы трубы, а в другом должен быть список доступных диаметров для выбранного типа трубы.

Всякий раз, когда пользователь выбирает тип трубы, другое поле со списком должно обновлять список доступных диаметров.

Свойства AvailableDiameters и RoutingPipeTypeName являются статическими в классе Context, который реализует интерфейс INotifyPropertyChanged. В xaml я установил привязки к этим свойствам, а в коде также DataContext.

Проблема в том, что список диаметров обновляется только один раз при инициализации вида.

При отладке я вижу, что значения поля поддержки свойств обновляются правильно при изменении выбора имени типа трубы, только в пользовательском интерфейсе список доступных диаметров не обновляется...

Класс контекста:

public class Context : INotifyPropertyChanged
{
    public static Context This { get; set; } = new Context();
    public static string RoutingPipeTypeName
    {
        get => _routingPipeTypeName;
        set
        {
            if (_routingPipeTypeName != value)
            {
                _routingPipeTypeName = value;

               This.OnPropertyChanged(nameof(RoutingPipeTypeName));
            }
        }
    }

    public static List<double> AvailableDiameters
    {
        get => _availableDiameters;
        set
        {
            //check if new list's elements are not equal
            if (!value.All(_availableDiameters.Contains))
            {
                _availableDiameters = value;
                This.OnPropertyChanged(nameof(AvailableDiameters));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

xaml:

<ComboBox Width = "80" SelectedValue = "{Binding Path=RoutingPipeTypeName, Mode=OneWayToSource}">
                    <ComboBoxItem Content = "Example pipe type 1"></ComboBoxItem>
                    <ComboBoxItem Content = "Example pipe type 2"></ComboBoxItem>
</ComboBox>

<ComboBox Width = "80" SelectedValue = "{Binding Path=RoutingDiameter, Mode=OneWayToSource}" ItemsSource = "{Binding Path=AvailableDiameters, Mode=OneWay}">
                </ComboBox>

код позади:

public Context AppContext => Context.This;

public MyView()
{
    InitializeComponent();

    Instance = this;
    DataContext = AppContext;
}

И клиентский класс, отвечающий за обновление списка диаметров:

public void InitializeUIContext()
{
    Context.This.PropertyChanged += UIContextChanged;

    if (Cache.CachedPipeTypes.Count > 0)
        Context.RoutingPipeTypeName = Cache.CachedPipeTypes.First().Key;
}

private void UIContextChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(Context.RoutingPipeTypeName))
    {
        Context.AvailableDiameters = Cache.CachedPipeTypes.First().Value.GetAvailableDiameters();
    }
}

Я ожидал, что такая настройка будет обновлять поле со списком диаметров каждый раз, когда выбор изменяется в свойстве типов труб. Вместо этого он обновляет его только один раз, когда представление инициализируется... Почему?

Я не вижу свойства RoutingDiameter.

Andy 17.04.2019 11:43

Это простое свойство.

adam.k 17.04.2019 12:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
426
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Не используйте статические свойства для привязки к объекту (который вы правильно передали в DataContext вашего представления).

Объявите свойства без модификатора static и замените This.OnPropertyChanged на OnPropertyChanged:

public string RoutingPipeTypeName
{
    get => _routingPipeTypeName;
    set
    {
        if (_routingPipeTypeName != value)
        {
            _routingPipeTypeName = value;
            OnPropertyChanged(nameof(RoutingPipeTypeName));
        }
    }
}

Вы также должны удалить static This из своего класса Context и просто написать

public Context AppContext { get; } = new Context();

теперь это работает. Но неужели для такой привязки нельзя использовать статические свойства? Эти свойства используются в нескольких местах моего решения. Вот почему я сделал их статическими, теперь я настроил настройку так, чтобы она работала без статики. Но все же мне любопытно.

adam.k 17.04.2019 12:36

Привязка к статическим свойствам, конечно, возможна, но вы не будете устанавливать DataContext представления для этих привязок, потому что не будет источника объект. У них другой синтаксис, см., например. здесь: stackoverflow.com/a/31611110/1136211

Clemens 17.04.2019 12:39

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