簡體   English   中英

將可見性綁定到靜態屬性

[英]Binding visibility to static property

我有一個帶有標簽的控件,我想基於該控件所有實例的全局菜單項隱藏或顯示。 如果單擊按鈕以隱藏標簽,則要隱藏所有標簽。

我的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,因為無法從我的靜態屬性引用非靜態屬性更改的處理程序。

我覺得這也許不是執行此操作的最佳方法,但是我真的很想一個按鈕(比實際控件高很多級別)來驅動所有實例的可見性。

CodeNaked的解決方案可以工作,但是它使用Singleton在進行單元測試時存在缺點。 我更喜歡通過在應用程序根目錄只有一個設置實例(即App -class)來解決全局訪問問題。

例如

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; }
    ...
}

您可以執行以下操作:

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"

我發現了一種la腳的解決方法:

    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的解決方案,但我想將其提供進行討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM