2009-06-04 123 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();