У меня есть представление с двумя выпадающими списками. В одном пользователь выбирает имя типа трассы трубы, а в другом должен быть список доступных диаметров для выбранного типа трубы.
Всякий раз, когда пользователь выбирает тип трубы, другое поле со списком должно обновлять список доступных диаметров.
Свойства 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();
}
}
Я ожидал, что такая настройка будет обновлять поле со списком диаметров каждый раз, когда выбор изменяется в свойстве типов труб. Вместо этого он обновляет его только один раз, когда представление инициализируется... Почему?
Это простое свойство.





Не используйте статические свойства для привязки к объекту (который вы правильно передали в 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();
теперь это работает. Но неужели для такой привязки нельзя использовать статические свойства? Эти свойства используются в нескольких местах моего решения. Вот почему я сделал их статическими, теперь я настроил настройку так, чтобы она работала без статики. Но все же мне любопытно.
Привязка к статическим свойствам, конечно, возможна, но вы не будете устанавливать DataContext представления для этих привязок, потому что не будет источника объект. У них другой синтаксис, см., например. здесь: stackoverflow.com/a/31611110/1136211
Я не вижу свойства RoutingDiameter.