Связывание статического свойства и реализация INotifyPropertyChanged - PullRequest
4 голосов
/ 13 января 2011

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

Все примеры используют следующий XAML:

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

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

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

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

Второй подход - использовать 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 не статично, но здесь оно статично ).

В этот момент я сдался.

Есть идеи?

Ответы [ 3 ]

11 голосов
/ 13 января 2011

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

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

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

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

2 голосов
/ 02 февраля 2013

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

Создайте статический 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; }
    }
0 голосов
/ 22 июля 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

...