【问题标题】:WPF OneWay binding works only onceWPF OneWay 绑定只工作一次
【发布时间】:2019-04-17 09:29:16
【问题描述】:

我有一个有两个组合框的视图。一个是用户选择布线管道类型名称的位置,另一个是所选管道类型的可用直径列表。

每当用户选择管道类型时,另一个组合框应更新可用直径列表。

AvailableDiameters 和 RoutingPipeTypeName 属性在 Context 类中是静态的,它实现了 INotifyPropertyChanged 接口。在 xaml 中,我在 DataContext 后面的代码中设置了对这些属性的绑定。

问题是直径列表仅在视图初始化时更新一次。

在调试时,我可以看到,当管道类型名称的选择发生更改时,属性支持字段的值会正确更新,只有在 UI 中,可用直径列表不会更新...

上下文类:

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 属性。
  • 这只是一个简单的属性。

标签: c# wpf data-binding


【解决方案1】:

不要使用静态属性绑定到对象(您已正确传递给视图的DataContext)。

声明不带static修饰符的属性并将This.OnPropertyChanged替换为OnPropertyChanged

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

您还应该从 Context 类中删除 static This 并简单地编写

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

【讨论】:

  • 现在可以了。但是这种绑定真的不能使用静态属性吗?这些属性在我的解决方案中的多个地方使用。这就是我将它们设为静态的原因,现在我调整了设置,使其在没有静态的情况下工作。但我还是很好奇。
  • 绑定到静态属性当然是可能的,但是您不会为这些绑定设置视图的 DataContext,因为不会有源 object。它们有不同的语法,参见例如这里:stackoverflow.com/a/31611110/1136211
猜你喜欢
  • 2020-08-09
  • 2020-12-25
  • 2023-03-17
  • 2016-10-18
  • 2021-09-30
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
相关资源
最近更新 更多