2009-06-04 3 views
0

У меня есть два элемента управления, которые привязаны к одному и тому же свойству зависимости «Погода». В первом элементе управления вы помещаете текущую погоду, а другая отображает прогноз.Правильный способ сделать это - привязка к свойствам

В моем XAML первого элемента управления я привязываю TextBox, который содержит «Влажность» следующим образом.

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

Всякий раз, когда изменения влажности, я хочу другой контроль, чтобы сделать что-то, однако меняется только влажность не меняет погоду - так другой контроль не уведомила. Изменение влажности должно изменить весь прогноз.

(я на самом деле не пишу приложение погоды, но только с помощью выше в качестве примера.)

Моего вопроса: что это правильный способ сделать это? Единственный способ, о котором я могу думать, - установить обработчик события SourceUpdated в TextBox, который касается свойства Weather. Есть ли более элегантный способ сделать это?

Благодаря

+1

Можете ли вы предоставить дополнительную информацию о том, как вы показываете прогноз и как это относится к вашему отображению Влажности? Это все делается одним контролем? Кроме того, существует внутренняя взаимосвязь между влажностью и другим свойством в объекте «Погода»? Вы посмотрели интерфейс INotifyPropertyChanged? –

ответ

1

Я предполагаю, что причина, по которой вы хотите, чтобы другой элемент управления делал что-то, связан с тем, что влажность влияет на другое свойство погоды/прогноза. В этом случае вы реализуете INotifyPropertyChanged, как и в ответе rmoore, и убедитесь, что при изменении влажности он либо явно меняет другое свойство, вызывая его уведомление об обновлении, либо отправляет уведомление о его обновлении, например:

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

Да, это лучше всего соответствует моему сценарию - спасибо, я его реализую так –

1

Значение по умолчанию для свойства UpdateSourceTrigger на TextBox связывания является «LostFocus» одна вещь, которую вы должны сделать, это изменить это PropertyChanged, то свойство Влажность будет отражать любые изменения, как вы вводите их в TextBox ,

Далее, вы хотите, чтобы убедиться, что ваш Погода Класс реализует 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 
    } 

Это будет гарантировать, что пользовательский интерфейс уведомляется о любых изменениях в собственности влажности.

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(); 
Смежные вопросы