2013-04-22 113 views
1

有一個實現INotifyPropertyChanged接口這樣的類:如何做一個XAML屬性綁定到INotifyPropertyChanged的對象

public class ColorNotify : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private SolidColorBrush bindableColor; 
    public SolidColorBrush BindableColor 
    { 
     get { return bindableColor; } 
     set 
     { 
      bindableColor = value; 
      OnPropertyChanged("BindableColor"); 
     } 
    } 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

一個在我MainPage.xaml.cs中字段的存在是這樣的:

private ColorNotify DisabledColor; 

但我也試過上述領域的屬性,而不是像這樣:

private ColorNotify disabledColor; 
public ColorNotify DisabledColor 
{ 
    get 
    { return disabledColor; } 
    set 
    { disabledColor = value; } 
} 

同樣在MainPage.xaml.cs中是這樣的方法:

private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs Lgd_Refreshed_EvArgs) 
{ 
    LayerItemViewModel layerItmViewMdl; 
    ObservableCollection<LayerItemViewModel> layerItms; 

    layerItmViewMdl = Lgd_Refreshed_EvArgs.LayerItem; 
    Layer legendItemLyr = layerItmViewMdl.Layer; 

    if (!legendItemLyr.IsInitialized) 
    { 
     DisabledColor = new ColorNotify(); 
     DisabledColor.BindableColor = new SolidColorBrush(Colors.Red); 
    } 
    ... 
    ... 
} 

在MainPage.xaml我有這樣的:

<esri:Legend 
     Map="{Binding ElementName=theMap}" 
     LayerIDs="..." 
     Refreshed="Legend_Refreshed"> 
       <esri:Legend.MapLayerTemplate> 
         <DataTemplate> 
           <StackPanel Orientation="Horizontal" Width="Auto"> 
             <CheckBox Content="{Binding Label}" 
              Width="Auto" 
              IsChecked="{Binding IsEnabled, Mode=TwoWay}" 
           IsEnabled="{Binding IsInScaleRange}" 
              Foreground="{Binding Source=DisabledColor, Path=BindableColor}"> 
             </CheckBox> 
             <Slider Maximum="1" 
              Value="{Binding Layer.Opacity, Mode=TwoWay}" 
              Width="80" /> 
           </StackPanel> 
         </DataTemplate> 
... 
... 
... 
</esri:Legend> 

注意上面的XAML代碼:

Foreground="{Binding Source=DisabledColor, Path=BindableColor}"> 

即沒沒有工作。

然後我想這在XAML:

Foreground="{Binding BindableColor}" 

但是,這並沒有工作,要麼 如何綁定前景到ColorNotify類的BindableColor財產? 綁定到INotifyPropertyChanged對象時,XAML綁定應該如何? (不通過MVVM)

+2

作出這樣的字段的屬性,並做'DisabledColor.BindableColor'作爲您的路徑 – NSGaga 2013-04-22 15:40:20

+0

順便說一句,我已經嘗試尋找這個鏈接的類似問題,但我沒有看到一個解決方案。 http://stackoverflow.com/questions/1962149/how-can-i-bind-a-background-color-in-wpf-xaml?rq=1 – Beebok 2013-04-22 15:46:21

+0

NSGaga,你是說我應該把「ColorNotify DisabledColor」變成屬性?如果綁定是:「{Binding Path = DisabledColor.Bindablecolor}」? – Beebok 2013-04-22 15:51:52

回答

1

編輯:基於下面的評論的討論,我想你應該有一個Convert方法是這樣創造的IValueConverter

return new SolidColorBrush((bool)value ? Colors.Black : Colors.Red); 

比方說,你IValueConverter類被命名爲InitializedColorConverter,在一個命名空間中」已添加爲xmlns local。在XAML中像這樣使用它:

<UserControl.Resources> 
    <local:InitializedColorConverter x:Key="InitializedColorConverter" /> 
</UserControl.Resources> 
... 
Foreground="{Binding IsInitialized, Converter = {StaticResource InitializedColorConverter}}" 

End Edit。我會離開這裏休息,因爲它可能具有類似人的問題是有用的:

你需要在MainPage改變字段爲公共財產:

public ColorNotify DisabledColor { get; private set; } 

如果你想綁定在DisabledColor本身發生更改時更新,MainPage(以及此屬性)也實施INotifyPropertyChanged

獲得正確值限制的一種較簡單的方法是以編程方式進行。要做到這一點,把你的對象上的Loaded處理程序:

<CheckBox Content="{Binding Label}" 
      Width="Auto" 
      IsChecked="{Binding IsEnabled, Mode=TwoWay}" 
      IsEnabled="{Binding IsInScaleRange}" 
      Loaded="MyCheckBoxLoaded"> 

,有你的處理器做這樣的事情:

private void MyCheckBoxLoaded(object sender, System.Windows.RoutedEventArgs e) 
{ 
    var cb = (CheckBox)sender; 
    cb.SetBinding(Control.ForegroundProperty, 
new System.Windows.Data.Binding("DisabledColor.Bindablecolor") { Source = this }); 
} 

這似乎令人費解的原因是Source需求,成爲您MainPage ,不幸的是,在Silverlight中,這並不像看起來那麼容易。

如果您DisabledColor頁面生命週期內不會改變,你可以保持一個私有字段(標記它readonly保證這是真的),併爲此在替代處理器:

cb.SetBinding(Control.ForegroundProperty, 
new System.Windows.Data.Binding("Bindablecolor") { Source = this.DisabledColor }); 
+0

我不能使用複選框加載事件上面的XAML中顯示的「Legend」元素將創建許多MapLayerElement對象(每個地圖圖層一個),這意味着將有有很多複選框。如果我使用複選框Loaded event,t我不能確定哪個複選框是哪個MapLayerElement的哪一部分,以及哪個Map Layer被該MapLayerElement引用。 – Beebok 2013-04-22 21:00:51

+0

第2部分,每次創建MapLayerElement時,都會調用「Legend」元素的Legend_Refreshed方法。從該方法中,我可以使用Lgd_Refreshed_EvArgs獲取對地圖圖層的引用,以便我可以確定Map圖層是否已初始化。然後,如果它沒有被初始化,我改變複選框的顏色。 – Beebok 2013-04-22 21:01:43

+0

如果'DisabledColor'的作用域是'MainPage'的一個實例是有意義的,我沒有看到我的代碼有什麼問題。我只注意到你實際在代碼示例中創建並設置的'DisabledColor'是'Legend_Refreshed'中的局部變量。如果'MainPage'的範圍有意義,那就使用它;如果你在任何地方都使用'INotifyPropertyChanged'來設置屬性,'Loaded'可能發生在'Legend_Refreshed'之前並不重要。如果這個範圍沒有意義,請指定什麼範圍(例如'MapLayerElement'的實例?)。 – 2013-04-22 21:09:12

0

如果更改/初始化

private ColorNotify DisabledColor; 

後視圖/視圖模型加載,那麼你就需要這個屬性更改爲公共和實施INotifyPropertyChange它也和你一樣做了上ColorNotify。

+0

我沒有使用MVVM。 DisabledProperty字段公開,但它不起作用 – Beebok 2013-04-22 21:03:58

相關問題