2012-03-20 6 views
6

Posiadałem zmienną, która nie była statyczna, a INotifyPropertyChanged wdrożono pomyślnie. Potem próbowałem uczynić go globalnym, więc zmieniono go na statyczną zmienną. Ale tym razem INotifyPropertyChanged nie działa. Jakieś rozwiązanie?INotifyPropertyChanged dla zmiennej statycznej

+0

możliwy duplikat [Oprawa własności statyczne] (http://stackoverflow.com/questions/936304/binding-to-static-property) –

Odpowiedz

21

INotifyPropertyChanged działa na właściwościach instancji. Jednym z rozwiązań jest użycie wzorca singleton i zachowanie INotifyPropertyChanged, a drugim użycie własnego zdarzenia do powiadomienia słuchaczy.

przykład Singleton

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 W WPF 4.5, wprowadzono nieruchomość zmieniła mechanik odpowiedzialny za właściwości statycznych:

Można użyć właściwości statycznych jako źródło wiążącej danych. Silnik powiązania danych rozpoznaje, kiedy wartość właściwości zmieni się, jeśli zostanie wywołane zdarzenie statyczne . Na przykład, jeśli klasa SomeClass definiuje właściwość statyczną o nazwie MyProperty, SomeClass może zdefiniować zdarzenie statyczne , które jest wywoływane, gdy wartość MyProperty zmienia się. Zdarzenie statyczne może wykorzystywać jedną z następujących sygnatur.

public static event EventHandler MyPropertyChanged; 
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; 
+3

+1 za sugestię singletona –

+0

Mały przykład? – Shibli

+0

@Shilbi Mały przykład czego? – chopikadze

5

Bardzo dobrym przykładem, użyłem go do pewnych ogólnych ustawień aplikacji, kiedy chcę się wiązać pewne własności online komponentów

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

Ustaw właściwości startowe:

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

Powiąż to z właściwościami komponentów

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> 

Kiedy gdzieś zmienić tę wartość w aplikacji jak „Preferencje” -> DataGrid FontSize - aby automatycznie aktualizować tę właściwość dla powiązań z 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

Dziękuję bardzo za ten przykład, dokładnie to, czego potrzebowałem. To działa przyjemność! – RobHurd