2011-04-15 77 views
2

我有一个控件,它上面有一个标签,我想隐藏或显示基于全局菜单项的所有实例的控件。如果我点击按钮隐藏标签,我想隐藏全部其中。将可见性绑定到静态属性

我的XAML看起来是这样的:

<TextBlock Name="_label" Visibility="{Binding LabelShown}" VerticalAlignment="Center" HorizontalAlignment="Center"/>

在我的代码

后面我有一个属性:

private static Visibility _labelShown; 
    public static Visibility LabelShown 
    { 
     get { return _labelShown; } 
     set { _labelShown = value; } 
    } 

我设置DataContext = this;

当我改变静态属性,什么都没发生。我认为这是因为没有控件获取属性更改通知。我无法在其上实现INotifyPropertyChanged,因为我无法从静态属性中引用非静态属性更改的处理程序。

我觉得也许这不是最好的方式来做到这一点,但我真的很想有一个按钮(在我的实际控制之上的许多级别)驱动所有实例的可见性。

回答

3

CodeNaked的解决方案可以工作,但它使用单元测试时有缺点的单例。我更喜欢通过在应用程序根目录下有一个设置实例来处理全局访问问题,即App-类。

例如

public partial class App : Application 
{ 
    private static Settings _settings = new Settings(); 
    public static Settings Settings 
    { 
     get { return _settings; } 
    } 

     ... 

此属性包含应用程序的所有设置。结合则是这样的:

"{Binding Source={x:Static local:App.Settings}, Path=LabelsShown}" 

编辑:如果你担心的依赖,你也可以注入到在你需要它的任何类的构造函数的设置参考,使用它的最小接口。

例如

public class MyControl : ContentControl 
{ 
    public interface IMyControlSettings 
    { 
     public bool LabelsShown { get; set; } 
    } 

    private IMyControlSettings _settings; 

    public MyControl(IMyControlSettings settings) 
    { 
     _settings = settings; 
     DataContext = _settings; // For easy binding, in most cases you probably do not want to do that since it prevents DataContext inheritance. 
    } 
} 
public class Settings : Test.MyControl.IMyControlSettings, INotifyPropertyChanged 
{ 
    public bool LabelsShown { get; set; } 
    ... 
} 
+0

的伟大工程。我也可以使用其他许多设置。谢谢!我也喜欢注射。这将简化绑定,并使其更清晰。 – captncraig 2011-04-15 17:20:28

2

你可以做这样的事情:

public class MySettings : INotifyPropertyChanged { 
    private MySettings() { 
    } 

    private Visibility _labelShown; 
    public Visibility LabelShown 
    { 
     get { return _labelShown; } 
     set { 
      _labelShown = value; 
      // Raise PropertyChanged event for LabelShown 
     } 
    } 

    private static MySettings _instance; 
    public static MySettings Instance 
    { 
     get { 
      if (_instance == null) 
       _instance = new MySettings(); 
      return _instance; 
     } 
    } 
} 

然后绑定到它像{Binding Path=LabelShown, Source={x:Static local:MySettings.Instance}}

你需要补充一点的是当地的xmlns这将是像xmlns:local="clr-namespace:MyNamespace"

0

我发现有点蹩脚的解决方法:

public static Visibility LabelShown 
    { 
     get { return _labelShown; } 
     set 
     { 
      _labelShown = value; 
      if (StaticEvent != null) 
      { 
       StaticEvent(); 
      } 
     } 
    } 

    private static event Action StaticEvent; 

    public event PropertyChangedEventHandler PropertyChanged 
    { 
     add { StaticEvent +=() => value(this, new PropertyChangedEventArgs("LabelShown")); } 
     remove { StaticEvent -=() => value(this, new PropertyChangedEventArgs("LabelShown")); } 
    } 

它的工作原理,但我有点担心删除处理程序实际上能够删除这样的匿名方法。如果处理了很多控件,会导致内存问题吗?

我倾向于选择CodeNaked的解决方案,但我想提供这个讨论。