2012-06-13 5 views
0

У меня этот сценарий хорошо, я позволю модели объяснить.Как программно обновить wpf C#?

public class ScheduleMonthlyPerDayModel 
{ 
    public DateTime Date { get; set; } 

    public string Day 
    { 
     get 
     { 
      return Date.Day.ToString(); 
     } 
    } 

    ObservableCollection<AppointmentDTO> _appointments; 
    public ObservableCollection<AppointmentDTO> Appointments 
    { 
     get 
     { 
      return _appointments; 
     } 
     set 
     { 
      _appointments = value; 

      if (value.Count > 0) 
       NotifyOfPropertyChange(() => HasSchedule); 
     } 
    } 

    public bool BelongsToCurrentMonth 
    { 
     get; 
     set; 
    } 

    public bool HasSchedule 
    { 
     get 
     { 
      return _appointments.Count > 0 ? true : false; 
     } 
    } 

    public ScheduleMonthlyPerDayModel() 
    { 
     _appointments = new ObservableCollection<AppointmentDTO>(); 
    } 

    public void ClearCollection() 
    { 
     _appointments.Clear(); 
    } 
} 

public class ScheduleMonthlyPerWeekModel 
{ 
    public ScheduleMonthlyPerDayModel Sunday{get; set;} 

    public ScheduleMonthlyPerDayModel Monday{get; set;} 

    public ScheduleMonthlyPerDayModel Tuesday{get; set;} 

    public ScheduleMonthlyPerDayModel Wednesday{get; set;} 

    public ScheduleMonthlyPerDayModel Thursday{get; set;} 

    public ScheduleMonthlyPerDayModel Friday{get; set;} 

    public ScheduleMonthlyPerDayModel Saturday{get; set;} 
} 

привязок к XAML работе с проблеск XAML как это:

headereditemscontrol itemsSource= weekcollection, где weekcollection является объектом schedulemonthlyperweekmodel.

Внутри этого headereditemscontrol я шаблонного каждый день для каждого свойства schedulemonthlyperweekmodel следующим образом:

<Grid.ColumnDefinitions> 
    <ColumnDefinition /> 
    <ColumnDefinition /> 
</Grid.ColumnDefinitions> 
<Grid.RowDefinitions> 
    <RowDefinition Height="Auto" /> 
    <RowDefinition Height="*" /> 
</Grid.RowDefinitions> 
<TextBlock Grid.Row="0" Style="{StaticResource CalendarDates}" Text="{Binding Path=Saturday.Day}" /> 
<ListBox Grid.Row="1" Grid.ColumnSpan="2" Padding="0" 
     ItemsSource="{Binding Path= Saturday.Appointments}" 
     ItemTemplate="{StaticResource myItemStyle}" 
     Visibility="{Binding Path=Saturday.HasSchedule, Converter={StaticResource BoolToVisibilityConverter}}" /> 

В принципе, я пытаюсь добиться ежемесячного представления с каждым днем, имеющий набор назначений. Моя проблема заключается в том, что когда я программно добавляю элементы к примеру, например, коллекция saturday.appointments, через отладочное добавление элементов, имеет успех и уведомляет основную коллекцию (weekcollection), не обновляет пользовательский интерфейс.

Что я хотел бы достичь: после добавления предполагаемого назначения на соответствующий день/даты пользовательский интерфейс также будет соответствующим образом обновляться, но как мне это сделать?

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

+0

Что такое 'NotifyOfPropertyChange', и я не вижу внедренного INotifyPropertyChanged. –

+0

Если вы привязываете DataSource элемента управления, вам не нужно ничего «обновлять». –

+0

Прямо сейчас, если вы добавляете элемент в коллекцию Appointments, он должен автоматически показывать этот элемент в ListBox. Однако привязка видимости не обновляется, когда список переходит из пустого в заполненный. Это правда? –

ответ

1

Проблема с вашей видимостью заключается в том, что она связывает свойство readonly, которое вычисляет значение на , получает. Поэтому нет способа сообщить, что он изменился.

Свойство HasSchedule должно знать, когда изменяется свойство Назначение. Настройщик для свойства Appointment знает только, когда изменяется весь список. В вашем случае вам нужно знать, когда изменяется содержимое .

ObservableCollection есть событие, которое говорит вам, когда содержимое изменяется список, называемый CollectionChanged. Вы должны сделать следующее, чтобы уведомить, что ваше имущество HasSchedule изменилось, используя это событие:

ObservableCollection<AppointmentDTO> _appointments; 
public ObservableCollection<AppointmentDTO> Appointments 
{ 
    get 
    { 
     return _appointments; 
    } 
    set 
    { 
     if (_appointments != value) 
     { 
      if (_appointments != null) 
       _appointments.CollectionChanged -= Appointments_CollectionChanged; 

      _appointments = value; 

      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("HasSchedule")); 

      if (_appointments != null) 
       _appointments.CollectionChanged += Appointments_CollectionChanged; 
     } 
    } 
} 

void Appointments_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs("HasSchedule")); 
} 

Это предполагает, что, как вы сказали, вы реализовали INotifyPropertyChanged в вашем ViewModel. В этом случае каждый раз, когда ваша коллекция каким-то образом изменяется, она уведомляет об изменении свойства HasSchedule.Связывание обновит значение и обновит видимость, если он изменился.

+0

ошибка на моем конце. propertychanged создается таким образом: public event PropertyChangedEventHandler СвойствоChanged = delegate {}; из viewmodelbase. – user1454041

+0

попробовал код и вместо моего предыдущего наследования Viewmodelbase я изменил его с помощью INotifyPropertyChanged, перекомпилировал, затем снова проверил, список не показывался после добавления назначений. – user1454041

+0

еще одна вещь, я проверил после добавления одного элемента в коллекцию встреч, если значение hasschedule изменяется, так оно и есть, поэтому я думаю, проблема в том, что новое значение bool не отражает или не обновляет xaml. – user1454041

3

Как предложил Ник, использование интерфейса INotifyPropertyChanged является ключевым.

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

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

На самом деле это очень просто реализовать и использовать, и это волнует УДИВИТЕЛЬНОЕ. Если вы не хотите использовать это, возможно, вам просто нравится использовать winform. =)

Надеюсь, это поможет.

+0

да моя ошибка действительно. как упоминалось выше, я унаследовал от класса, который реализует inotify. я, вероятно, был сонлив и случайно удалил его, не заметив, что ScheduleMonthlyPerDayModel на самом деле выглядит как этот «публичный класс ScheduleMonthlyPerDayModel: ViewModelBase», где viewmodelbase наследует от inotifypropertychanged. очень жаль, что не заметил недостающий код. – user1454041

Смежные вопросы