2011-10-28 14 views
3

今は1ヶ月しか表示していないカレンダーがあります。私はユーザーにコンボボックスから月と年を選択させ、カレンダーの更新をさせようとしています。私は慣れているobservablecollectionを使ってバインドしています。私はどのようにINotifyPropertyChangedが動作するかについての手掛かりはありません。私はかつてこれを使ったことがない。助けやアドバイスをいただければ幸いです。これは私がこれまで持っているものです。INotifyPropertyChangedとObservableCollection WPF

public class Schedule : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public void Update(int propertyName) 
    { 
     if (propertyName != null) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) 
       handler.Invoke(this, new PropertyChangedEventArgs(propertyName.ToString())); 
     } 
    } 


    // public void UpdateCal(PropertyChangedEventArgs e) 
    // { 
    // if (PropertyChanged != null) 
    //  PropertyChanged(this, e); 
    // } 
    public string MonthWeek { get; set; } 
    public string Year { get; set; } 
    public string Month { get; set; } 
    public string day { get; set; } 
    public string WeekOfYear { get; set; } 
    public string dayofweek { get; set; } 

    // public string month { 
    // get {return Month; } 
    // set 
    // { 
    //  UpdateCal(new PropertyChangedEventArgs("month")); 
     // } 
    // } 
    public int WeekNo { get; set; } 
    public int WeekDay { get; set; } 
    public DateTime Date { get; set; } 
} 

---これは----グリッド上

  public SchedulePage(MainWindow parentForm) 
    { 
     InitializeComponent(); 

     pick = Convert.ToInt32(comboMonth.SelectedItem) + 1; 
     _parentForm = parentForm; 
     // DateTime date = new DateTime(year, month, day); 
     var t = new List<Schedule>(); 
     DateTime curr = DateTime.Now; 
     // comboMonth.Items.Add(curr.Month); 
     DateTime newcurr = new DateTime(2011, pick, 1); 
    // pickdate = datePickercal.SelectedDate; 
     // DateTime newcurr = new DateTime(curr.Year, curr.Month, 1); 
     var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar; 
     var ms = cal.GetWeekOfYear(new DateTime(newcurr.Year, newcurr.Month, 1), System.Globalization.CalendarWeekRule.FirstDay, System.DayOfWeek.Sunday); 
     for (var i = 1; newcurr.Month == pick; newcurr = newcurr.AddDays(1)) 
     { 
      var sched = new Schedule(); 
      var month_week = (newcurr.Day/7) ; 
      sched.MonthWeek = newcurr.GetWeekOfMonth().ToString(); 
      sched.Month = newcurr.Month.ToString(); 
      sched.Year = newcurr.Year.ToString(); 
      sched.day = newcurr.Day.ToString(); 
      sched.WeekOfYear = cal.GetWeekOfYear(newcurr, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString(); 
      sched.dayofweek = newcurr.DayOfWeek.ToString(); 
      t.Add(sched); 

       _parentForm.bindings.schedule.Add(new Schedule { WeekNo = newcurr.GetWeekOfMonth()-1, WeekDay = (int)newcurr.DayOfWeek, day = newcurr.Day.ToString() }); 

     } 
     lblDate.Content = (newcurr.Month -1) + "/" + newcurr.Year; 

     DataContext = _parentForm.Bindings; 

を各日付を配置する場所を割り出し、別のクラス---そしてこのクラスであります作るobservablecollections -----

  public partial class BindingCamper 
{ // This class assist in binding campers from listview to the textboxes on the camperspage 
    public ObservableCollection<Camper> Campers { get; set; } 
    public ObservableCollection<Staff> StaffMembers { get; set; } 
    public ObservableCollection<Schedule> schedule { get; set; } 
    public BindingCamper() 
    { 
     Campers = new ObservableCollection<Camper>(); 
     StaffMembers = new ObservableCollection<Staff>(); 
     schedule = new ObservableCollection<Schedule>(); 
    } 

答えて

5

これは、あなたが一般的に実装する方法であるINotifyPropertyChanged

public class Schedule : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private string _monthWeek; 
    public string MonthWeek 
    { 
     get { return _monthWeek; } 
     set 
     { 
      if (value != _monthWeek) 
      { 
       _monthWeek = value; 
       OnPropertyChanged("MonthWeek"); 
      } 
     } 
    } 

    // And so on for other properties... 

} 

基本的には、プロパティが更新されるたびにPropertyChangedイベントをトリガーする必要があるだけで、すべてのセッターはOnPropertyChangedを呼び出す必要があります。 setterにカスタムロジックを追加する必要があるため、自動実装されたプロパティでは実行できないことに注意してください。

+0

自動実装されたプロパティでも実行できますが、そうしないことをお勧めします。 OnPropertyChangedは、コードを変更して起動するよりも、それを自己保持する方がよいでしょう。UIがOnPropertyChangedを起動できないようにする必要があるため、これはOneWayプロパティにのみ適用されます。 –

+0

@ m-y - 自動実装のプロパティでINotifyPropertyChangedをどのように実装できますか? – CodeNaked

+0

@my、クラス内のどこからでもOnPropertyChangedを呼び出すことができますが、その場合はイベントが発生するという保証はありません(例えば、プロパティがクラス外から更新されている場合) –

4

(プロパティがObservableCollectionであっても)プロパティにバインドすると、(プロパティの内容ではなく)PROPERTYを変更すると、PropertyChangedイベントが発生するはずです。

ObservableCollectionは、CollectionChangedイベントを発生させるときには自己完結型なので、ItemsSourceアイテム自体のイベントを起動する心配はありません。

XAML:

<!-- This says that ItemsSource is bound to the Campers property... --> 
<ItemsControl ItemsSource="{Binding Path=Campers, Mode=OneWay}" /> 

はCLASS:また

public class TheViewModel() 
{ 
    private ObservableCollection<Camper> _campers; 
    public ObservableCollection<Camper> Campers 
    { 
     get { return _campers; } 
     set 
     { 
      if (Equals(_campers, value)) return; 

      _campers = value; 
      RaisePropertyChanged("Campers"); //Or however you implement it 
     } 
    } 

    private void SomeFunc() 
    { 
     var bindingCamper = new BindingCamper(); 

     Campers = bindingCamper.Campers; //This will fire the event 
     //etc. 
    } 

}


、あなたはBindingCamper あなたのViewModelであるなら、あなたはそこに同じことを行います代わりに。

2

コードを後ろから変更してUIを更新する場合は、INotifyPropertyChangedインターフェイスを使用します。私はあなたがインターフェイスを実装し、それを使用するヘルパーを設定することを参照しているだけで、あなたは文字列を代わりに使用する必要がありますパラメータとしてintを使用してください。プロパティを設定すると、適切なPropertyNameを使用してヘルパーに電話するだけでよいです。

public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(String propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (null != handler) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

とUIを通知するイベントをトリガするには:このよう

NotifyPropertyChanged("YourPropertyName"); 

たぶん、あなたはあまりにも結合双方向に設定する必要がありますが、あなたが変更したい場合には、唯一の真のですプロパティもUIから取得できます。

関連する問題