Связывание статического свойства и реализация INotifyPropertyChanged

Я пытаюсь привязать статическое свойство некоторого класса к некоторому элементу управления. Я пробовал несколько реализаций, но у каждой есть проблема:

Во всех примерах используется следующий XAML:

 <Label Name="label1" Content="{Binding Path=text}"/>  

1-й подход - не используйте INotifyPropertyChanged

public class foo1
{
    public static string text { get; set; }
}

Проблема в том, что при изменении свойства «текст» элемент управления не уведомляется.

Второй подход - используйте INotifyPropertyChanged

public class foo1 : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private static string _text;
    public static string text
    {
        get { return _text; }
        set
        {
            _text = value;
            OnPropertyChanged("text");
        }
    }
}

Это не компилируется, потому что метод OnPropertyChanged () не является статическим и вызывается внутри статического метода.

Второй подход попробуйте 2: сделать метод OnPropertyChanged () статическим => он не компилируется, потому что OnPropertyChanged () теперь статичен и пытается использовать событие PropertyChanged, которое не является статическим.

Второй подход попробуйте 3: сделать событие «PropertyChanged» статическим => это не компилируется, потому что класс не реализует событие «INotifyPropertyChanged.PropertyChanged» (событие определено в интерфейсе «INotifyPropertyChanged» не статично, но здесь оно статично).

На этом я сдался.

Любые идеи?


person dana    schedule 13.01.2011    source источник


Ответы (3)


Я бы посоветовал у вас просто свойство экземпляра вернуть ваше статическое свойство следующим образом:

private static string _text;
public string text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("text");
    }
}

Однако это делает всю привязку сравнительно бессмысленной, поскольку уведомления об изменениях создаются только в одном экземпляре класса, а не в каждом экземпляре. Таким образом, будут обновлены только привязки, которые привязаны к свойству в конкретном экземпляре, в котором оно было изменено.

Лучшим методом было бы использование синглтона, как можно увидеть здесь.

person H.B.    schedule 13.01.2011

Использование синглтона будет самым простым и понятным для реализации. Если вы хотите пройти трудный путь без использования синглтона, вы можете использовать следующее.

Создайте статический PropertyChangedEventHandler, который вызывается из вашего статического свойства. Когда вы создаете новый экземпляр своего класса, зарегистрируйтесь, чтобы получить обратный вызов от статического события. Когда вы получите обратный вызов, вызовите OnPropertyChanged («текст»). БОЛЬШАЯ проблема с этим заключается в том, что вам нужно использовать WeakReference при регистрации для статического события. В противном случае ваш объект останется навсегда. Я пропустил этот шаг в коде.

Причина, по которой вам нужно перенаправить событие экземпляра, заключается в том, что тот, кто когда-либо регистрировал NotifyPropertyChanged, должен знать, кто является «отправителем» (т.е. экземпляр foo1 со свойством экземпляра на нем)

public class foo1 : System.ComponentModel.INotifyPropertyChanged
{
    // static property
    private static string _text = "static string";
    public static string static_text
    {
        get
        {
            return _text;
        }
        set
        {
            _text = value;
            OnStaticPropertyChanged("static_text");
        }
    }
    private static System.ComponentModel.PropertyChangedEventHandler staticpropChanged;
    static protected void OnStaticPropertyChanged(string pname)
    {
        System.ComponentModel.PropertyChangedEventArgs e = new System.ComponentModel.PropertyChangedEventArgs(pname);
        System.ComponentModel.PropertyChangedEventHandler h = staticpropChanged;
        if (h != null)
            h(null, e);

    }
    public foo1()
    {
        // really should use a weakreference here.. but leaving it out
        // for simplicity
        staticpropChanged += foo1_staticpropChanged;
    }

    void foo1_staticpropChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        // map the static name to the instance name
        if(e.PropertyName == "static_text") OnPropertyChanged("text");
    }
    // instance-property forwards to static
    public string text
    {
        get { return foo1.static_text; }
        set { foo1.static_text = value; }
    }
person shimpossible    schedule 02.02.2013
comment
пальцы вверх Я реализовал немного другое, см. ниже - person New Bee; 22.07.2015

    public static String StatusInformation
    {
        get { return _StatusInformation; }
        set { _StatusInformation = value; OnStaticPropertyChanged("StatusText"); }
    }

    #region Handlig Static Properties Changed
    private static System.ComponentModel.PropertyChangedEventHandler staticpropChanged;
    static protected void OnStaticPropertyChanged(string pname)
    {
        System.ComponentModel.PropertyChangedEventArgs e = new System.ComponentModel.PropertyChangedEventArgs(pname);
        System.ComponentModel.PropertyChangedEventHandler h = staticpropChanged;
        if (h != null)
            h(null, e);

    }
    private void Handler_PropertyChange(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        NotifyPropertyChanged(e.PropertyName);
    }
    #endregion
    public string StatusText
    {
        get { return ExchangeServices.StatusInformation; }
        set { ExchangeServices.StatusInformation = value; }
    }

таким образом, мне вообще не пришлось заниматься каким-либо делом. это было действительно полезно для создания одной строки состояния для всей моей программы и обновления ее из любого места и любого пользовательского элемента управления в моей постоянно расширяющейся программе.

Спасибо shimpossible

person New Bee    schedule 22.07.2015