假设我们有一个只有一个状态变量的简单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提供的数据绑定功能?
发布于 2011-04-21 18:11:01
您可以使用INotifyPropertyChanged。只需在给定的WindowXVisible发生CurrentState更改时发送更改通知(此为DP有一个回调)。
绑定通常可以通过DependencyProperty或INotifyPropertyChanged通知侦听更改(但与DP不同,必须手动发送)。
您可以使用这个工具自动生成通知调用(而不会增加代码的复杂性)。它甚至能很好地处理这些非平凡的情况。
编辑:
将其注册到PropertyMetadata of CurrentStateProperty中。
private static void OnCurrentStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
this.OnPropertyChanged("CurrentState");
this.OnPropertyChanged("Window1Visible");
this.OnPropertyChanged("Window2Visible");
}OnPropertyChanged只需调用PropertyChanged事件,并将其作为发送方,字符串作为属性名。
这将导致Window1Visible和Window2Visible绑定更新并获取新值。
顺便说一句,您应该尝试找出比Window1和WIndow2更好的名称。
发布于 2011-04-21 22:22:13
有几个好的答案,所以我不会直接提出一个具体的解决方案,但我会解决你所面临的普遍关注。您担心添加一些依赖属性机器来复制您已经拥有的看似简单的状态匹配概念,这可能是多余的,甚至更糟糕的是,它可能无法正常工作。
事实上,您将使用依赖属性基础结构而不是CLR基础结构重新实现相同的概念。是的,它会更详细一点,但这是一个坚实的东西,整个WPF的基础。例如,ListBox有一个需要保持同步的SelectedItem和SelectedIndex,就像在您的示例中一样。一旦你做对了,无论你做什么,他们永远不会失去同步。
唯一可见性可以更改的时间是状态更改时,因此您可以从状态更改回调设置可见性,只要您相信回调将被称为。实际上,即使没有依赖项属性,有时也会看到程序员使用此策略来避免在getter中为属性进行计算。因此,不要把它看作是一种冗余,而仅仅是实现同一目标的另一种方式。
发布于 2011-04-21 18:22:58
您可以绑定到CurrentState并编写转换为可见性的IValueConverter。
这个问题可能是有用的。
编辑-假设您需要一个依赖项属性来进行数据绑定。否则,INotifyPropertyChanged就更容易了。
https://stackoverflow.com/questions/5747899
复制相似问题