2011-10-28 2 views
3

지금은 한 달 만 표시하는 캘린더가 있습니다. 사용자가 콤보 상자에서 몇 달과 몇 달을 선택하고 캘린더 업데이트를 할 수있게하려고합니다. 내가 친숙한 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) : 당신이 BindingCamper 인 경우


또는

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. 
    } 

가}, 당신의 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에서.

관련 문제