如何以编程方式刷新wpf c#?

时间:2012-06-13 17:43:14

标签: c# wpf binding observablecollection

我有这个场景,我会让模型解释。

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里面,我每天都会对schedulemonlylyperweekmodel的每个属性进行模板化,如下所示:

<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),不刷新UI。

我想要实现的是:在我将假设的约会添加到相应的日期/日期后,用户界面也会相应地更新,但我该怎么做?

目前,只有当我更改/切换到不同然后返回时,UI才会更新,之后会很好地显示约会。我想自动化它,因为要求用户在看到约会列表之前切换到别的东西然后回来是很难看的。

2 个答案:

答案 0 :(得分:3)

正如Nick建议的那样,使用INotifyPropertyChanged接口是关键。

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

如果您希望ObsCollection了解属性更改,则必须实现此界面,如上面的链接所示。这将更新添加,删除或更改内容时绑定的UI控件。没有它,您实际上必须跟踪代码中的更改并手动更新它们。

它实际上非常容易实现和使用,它真是太棒了。如果您不想使用它,您可能只需使用winform即可。 =)

希望这有帮助。

答案 1 :(得分:1)

您的可见性问题在于它绑定到readonly属性,该属性计算 get 上的值。因此,没有办法通知它已经改变了。

您的HasSchedule属性需要知道约会属性何时更改。 Appointment属性的setter只知道整个列表何时更改。在您的情况下,您需要知道列表的内容何时更改。

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"));
}

正如您所说,这是假设您已在ViewModel中实现了INotifyPropertyChanged。在这种情况下,每次您的集合以某种方式更改时,它都会通知HasSchedule属性已更改。绑定将刷新值并更新可见性(如果已更改)。