WPF绑定顺序如何确保一个属性先于另一个属性绑定


<Controls:MyControl Mode="Mode1" Value="{Binding Path=Something}" />

我遇到的问题是,绑定发生在Mode属性被设置之前,当我在ListView的数据模板中使用这个控件时。

我如何确保模式总是在值绑定之前设置?

您可以做的是延迟绑定,因此您可以(几乎)确定在此之前设置了mode值。在。net 4.5中有一个延迟绑定属性。这里有一篇关于如何在。net 4.0中模拟的文章从。net 4.5到。net 4.0的绑定延迟属性

我个人会在viewModel (MVVM)中实现这一点,这种问题很容易解决。创建两个属性Mode和Something。当模式改变时,它应该触发"Something"属性也被改变(通过INotifyPropertyChanged接口)。

class MyViewModel : INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    private string _mode;
    public string Mode
    {
      get { return _mode; }
      set
      {
        _mode = value;
        OnPropertyChanged("Mode");
        // OnPropertyChanged("Something");
        // or build up via a method:
        // Something = DetermineFromMode(Mode);
      }
    }
    private string _something;
    public string Something
    {
      get { return _something;  }
      set
      {
        _something = value;
        OnPropertyChanged("Something");
      }
    }
  }

您是否尝试过在设置控件模式时为您的属性"Something"引发属性更改事件?你可以像这样在你的控件中获取属性"Something" -

Binding binding = BindingOperations.GetBindingExpression(this, this.Value).ParentBindingBase;
String propertyToRefresh = binding.Path.Path;
(this.DataContext as ViewModel).OnPropertyChange(propertyToRefresh);

我假设你的控件的DataContext是你的ViewModel的实例,它实现了INotifyPropertyChangedInterface。

如果你的Viemodel类OnPropertyChange方法不是公共的,或者你没有在你的控件中引用你的ViewModel类。你可以简单地在你的BindingExpression上调用updatettarget(),就像这样(由Thomas Levesque建议)-

BindingExpression binding = BindingOperations.GetBindingExpression(this, this.Value);
binding.UpdateTarget();

(我知道这是旧的,但我今天遇到这个问题,所以我被迫做一些调查)

看起来绑定是按照DependencyProperties定义的顺序发生的

例如,在MyControl.cs

public int Mode { get => (int)GetValue(ModeProperty); set => SetValue(ModeProperty, value); }
public static readonly DependencyProperty ModeProperty
    = DependencyProperty.Register(nameof(Mode), typeof(int), typeof(MyControl),
        new FrameworkPropertyMetadata(new PropertyChangedCallback(Mode_Changed)));
public string Result { get => (string)GetValue(ResultProperty); set => SetValue(ResultProperty, value); }
public static readonly DependencyProperty ResultProperty
    = DependencyProperty.Register(nameof(Result), typeof(string), typeof(MyControl),
        new FrameworkPropertyMetadata(new PropertyChangedCallback(Result_Changed)));
private static void Mode_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    //Mode changed. Update display.
}
private static void Result_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    //Result changed. Update display.
}

和XAML:

<controls:MyControl Result="You passed!"
                    Mode="3" />

由于ModeResult之前被定义为依赖属性,因此Mode将首先被设置。忽略XAML中赋值的顺序。

所以在理论上,要回答你的问题,确保首先定义Mode属性。这就解决了我的问题

最新更新