Привязка WPF OneWay работает только один раз - PullRequest
0 голосов
/ 17 апреля 2019

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

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

Свойства 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();
    }
}

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

1 Ответ

1 голос
/ 17 апреля 2019

Не используйте статические свойства для привязки к объекту (который вы правильно передали 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...