2009-06-04 121 views
0

我有兩個控件都綁定到相同的依賴項屬性「天氣」。 在第一個控件中放置當前天氣,另一個顯示預測。正確的做法 - 綁定到屬性

在我的第一個控件的XAML中,我綁定了一個包含「溼度」的TextBox,如下所示。

<TextBox Text="{Binding Weather.Humidity}" /> 

每當溼度的變化,我想其他的控制做一些事情,但只改變溼度不改變天氣 - 讓對方控制它不被通知。改變溼度應該改變整個預測。

(我不是真正寫的天氣應用程序,而只是使用上述作爲一個例子。)

我的問題:什麼是做到這一點的正確方法?我能想到的唯一方法是在觸摸Weather屬性的TextBox上設置SourceUpdated事件處理程序。有沒有更優雅的方式來做到這一點?

感謝

+1

你能否提供更多的信息,如何你正在顯示預測,以及這與你的溼度顯示相關嗎?這一切都是在單一控制下完成的嗎? 此外,溼度與「天氣」對象中另一個屬性之間是否存在內部關係?你看過INotifyPropertyChanged接口嗎? – 2009-06-04 14:44:49

回答

1

我假設你想要其他控制器做某件事情的原因是因爲溼度影響天氣/預測的其他屬性。在這種情況下,您可以實現INotifyPropertyChanged(如rmoore的答案中所述),並確保在修改溼度時,它會明確更改其他屬性,觸發其通知更新,或者發送更新通知,如下所示:

private int myHumidity; 
      public int Humidity 
      { 
        get 
        { 
          return this.myHumidity; 
        } 
        set 
        { 
          this.myHumidity = value; 
          NotifyPropertyChanged("Humidity"); 
          NotifyPropertyChanged("MyOtherProperty"); 
        } 
      } 
+0

是的,這與我的場景最匹配 - 謝謝我將這樣實現 – 2009-06-05 07:40:56

1

對一個TextBox綁定UpdateSourceTrigger屬性的默認值是「引發LostFocus」一件事你應該做的是改變的PropertyChanged,那麼當你在文本框中輸入他們的溼度屬性將反映任何變化。

接下來,你要確保你的天氣類實現INotifyPropertyChanged,就像這樣:

public class Weather : INotifyPropertyChanged 
    { 
     private int myHumidity; 
     public int Humidity 
     { 
      get 
      { 
       return this.myHumidity; 
      } 
      set 
      { 
       this.myHumidity = value; 
       NotifyPropertyChanged("Humidity"); 
      } 
     } 

     private void NotifyPropertyChanged(String info) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 

     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged; 

     #endregion 
    } 

這將確保UI通知的任何改變溼度財產。

0

一個簡單的綁定方案將是這樣的:

WPF Simple DataBinding http://i41.tinypic.com/2446v5w.jpg

這可能幫助:

<Window x:Class="BindingSample.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    WindowStartupLocation="CenterScreen"  
    Title="BindingDemo" Height="300" Width="300"> 
    <Grid> 
     <StackPanel Margin="20"> 
      <Slider Name="fontSizeSlider" Minimum="0" 
      Maximum="100" Value="{Binding Path=Weather.Humidity, Mode=TwoWay}"/> 

      <Label Content="Enter Humidity (between 0 to 100)" /> 
      <TextBox x:Name="_humidity" 
       Text="{Binding Path=Weather.Humidity, 
           Mode=TwoWay, 
           UpdateSourceTrigger=PropertyChanged}" 
      /> 
      <TextBlock Text=" "/> 
      <Label Content="Forecast: " /> 
      <TextBlock 
       Text="{Binding Path=Weather.Forecast}" 
       Foreground="Blue" 
       FontSize="{Binding ElementName=_humidity,Path=Text}" />    
     </StackPanel> 
    </Grid> 
</Window> 

和天氣類可以是東西如下:

public class DummyViewModel 
{ 
    public Weather Weather { get; set; }   

    public DummyViewModel() 
    { 
     this.Weather = new Weather(); 
    } 

    public DummyViewModel(int humidity):this() 
    { 
     this.Weather.Humidity = humidity; 
    } 
} 

public class Weather : INotifyPropertyChanged 
{ 
    #region - Fields - 

    private string _forecast;   
    private decimal _humidity;   


    #endregion // Fields 

    #region - Constructor   - 

    #endregion // Constructor 

    #region - Properties - 

    public string Forecast 
    { 
     get { return _forecast; } 
     set 
     { 
      if (value == _forecast) 
       return; 

      _forecast = value; 

      this.OnPropertyChanged("Forecast"); 
     } 
    } 


    public decimal Humidity 
    { 
     get { return _humidity; } 
     set 
     { 
      if (value == _humidity) 
       return; 

      _humidity = value; 

      this.OnPropertyChanged("Humidity"); 
      UpdateForeCast(); 
     } 
    }   

    #endregion // Properties 

    #region - Private Methods - 

    private void UpdateForeCast() 
    { 
     if (this.Humidity < 0 || this.Humidity > 100) 
      this.Forecast = "Unknown"; 
     else if (this.Humidity >= 70) 
      this.Forecast = "High"; 
     else if (this.Humidity < 40) 
      this.Forecast = "Low"; 
     else 
      this.Forecast = "Average"; 
    } 

    #endregion 

    #region INotifyPropertyChanged Members 

    /// <summary> 
    /// Raised when a property on this object has a new value. 
    /// </summary> 
    public event PropertyChangedEventHandler PropertyChanged; 

    /// <summary> 
    /// Raises this object's PropertyChanged event. 
    /// </summary> 
    /// <param name="propertyName">The property that has a new value.</param> 
    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

    #endregion // INotifyPropertyChanged Members 
} 

然後,你可以這樣:

public Window1() 
{ 
    InitializeComponent(); 

    this.DataContext = new DummyViewModel(40); 
} 

或者MV-VM風格

Window1 view = new Window1(); 
view.DataContext new DummyViewModel(40); 
view.Show();