让我们假设我们有一个只有一个状态变量的简单UI。该状态表示为枚举值,例如。 Phase1,Phase2等。取决于UI处于哪个状态(阶段),不同的UI元素,窗口应该是可见的还是隐藏的。
这是代码:
public enum Phases { Phase1, Phase2, Phase3 }
public class UIStateModel : DependencyObject
{
public static DependencyProperty CurrentStateProperty =
DependencyProperty.Register("CurrentStateProperty",
typeof(Phases),
typeof(UIStateModel));
public Phases CurrentState
{
get { return (Phases)GetValue(CurrentStateProperty); }
set { SetValue(CurrentStateProperty, value); }
}
public Visibility Window1Visible // Databound to Window1.Visibility
{
get
{
if (this.CurrentState == Phases.Phase1) return Visibility.Visible;
else return Visibility.Hidden;
}
}
public Visibility Window2Visible // Databound to Window2.Visibility
{
get
{
if (this.CurrentState == Phases.Phase2) return Visibility.Visible;
else return Visibility.Hidden;
}
}
...
}
问题在于,由于WindowXVisible属性不是DependencyProperty-s,因此无法使用上述代码进行数据绑定。如果我将所有属性都转换为DependencyProperty,则将冗余引入状态管理。除了使所有内容保持同步的额外负担外,它甚至可能变得不一致(如果我无法很好地同步)。
避免在UI状态管理中引入冗余但仍然利用DependencyProperty-s促进的数据绑定功能的正确方法是什么?
最佳答案
您可以使用INotifyPropertyChanged。当CurrentState更改时,只需发送给定WindowXVisible的更改通知(对此DP has a callback)。
绑定通常可以通过DependencyProperty或INotifyPropertyChanged通知(与DP不同,必须手动发送)来侦听更改。
您可以使用this tool自动生成通知调用(而不会稍微增加代码的复杂性)。它甚至可以很好地处理此类非平凡的案件。
编辑:
将其注册到CurrentStateProperty的PropertyMetadata中。
private static void OnCurrentStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
this.OnPropertyChanged("CurrentState");
this.OnPropertyChanged("Window1Visible");
this.OnPropertyChanged("Window2Visible");
}
OnPropertyChanged只需调用PropertyChanged事件,并将此作为发送方,并将字符串作为属性名称。
这将导致Window1Visible和Window2Visible绑定更新并获取新值。
顺便说一句,您应该尝试找出比Window1和WIndow2更好的名称。