INotifyPropertyChanged for static variable

前端 未结 2 1991
北海茫月
北海茫月 2020-12-09 21:13

I had a variable which was not static and INotifyPropertyChanged implemented succesfully. Then I tried to make it global, so turned it a static variable. But this time, INot

相关标签:
2条回答
  • 2020-12-09 22:02

    INotifyPropertyChanged works on instance properties. One solution is to use a singleton pattern and keep INotifyPropertyChanged, the other is to use your own event to notify listeners.

    Singleton example

    public sealed class MyClass: INotifyPropertyChanged
    {
       private static readonly MyClass instance = new MyClass();
       private MyClass() {}
    
       public static MyClass Instance
       {
          get 
          {
             return instance; 
          }
       }
    
       // notifying property
       private string privMyProp;
       public string MyProp
       {
           get { return this.privMyProp; }
    
           set
           {
               if (value != this.privMyProp)
               {
                   this.privMyProp = value;
                   NotifyPropertyChanged("MyProp");
               }
           }
       }
    
    
       // INotifyPropertyChanged implementation
       public event PropertyChangedEventHandler PropertyChanged;
    
       private void NotifyPropertyChanged(String info)
       {
           var handler = PropertyChanged;
           if (handler != null)
           {
               handler(this, new PropertyChangedEventArgs(info));
           }
       }
    }
    

    EDIT: In WPF 4.5, they introduced property changed mechanic for static properties:

    You can use static properties as the source of a data binding. The data binding engine recognizes when the property's value changes if a static event is raised. For example, if the class SomeClass defines a static property called MyProperty, SomeClass can define a static event that is raised when the value of MyProperty changes. The static event can use either of the following signatures.

    public static event EventHandler MyPropertyChanged;
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
    
    0 讨论(0)
  • 2020-12-09 22:16

    Very good example, I used it for some general settings in application, when I want to bind some property online to components

        public sealed class DataGridClass:INotifyPropertyChanged
    {
          private static readonly DataGridClass instance = new DataGridClass();
          private DataGridClass() { }
    
          public static DataGridClass Instance
           {
              get 
              {
                 return instance; 
              }
           }
    
        private int _DataGridFontSize {get;set;}
    
        public int DataGridFontSize
        {
            get { return _DataGridFontSize; }
            set { _DataGridFontSize = value;
                RaisePropertyChanged("DataGridFontSize");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void RaisePropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    

    Set startup properties:

    DataGridClass.Instance.DataGridFontSize = 14(or read from xml)
    

    Bind this to components properties

    xmlns:static="clr-namespace:MyProject.Static"
    <extgrid:ExtendedDataGrid x:Name="testGrid"  ClipboardCopyMode="IncludeHeader" AutoGenerateColumns="False">
    <extgrid:ExtendedDataGrid.Resources>
        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="FontSize" 
            Value="{Binding Source={x:Static static:DataGridClass.Instance},
            Path=DataGridFontSize, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
        </Style>
    </extgrid:ExtendedDataGrid.Resources>
    

    When you change this value somewhere in application like "Preferences"->DataGrid FontSize - to it automatically update this property for bindings with UpdateSourceTrigger

        private void comboBoxFontSize_DropDownClosed(object sender, EventArgs e)
        {
            DataGridClass.Instance.DataGridFontSize = Convert.ToInt32(comboBoxFontSize.Text);
        }
    
    
       <ComboBox Grid.Column="1" Grid.Row="0" Height="21" Width="75" Name="comboBoxFontSize" HorizontalAlignment="Left" 
                                  VerticalAlignment="Center"  DropDownClosed="comboBoxFontSize_DropDownClosed" 
                                  ItemsSource="{Binding Source={x:Static commands:ConstClass.ListOfFontSize},Mode=OneWay}" 
                                  SelectedItem="{Binding Source={x:Static static:DataGridClass.Instance},Path=DataGridFontSize, 
                            Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
    
    0 讨论(0)
提交回复
热议问题