0

私はこのシナリオをよく持っています。モデルで説明します。

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 内で、次のように、schedulemonthlyperweek モデルの各プロパティに対して毎日テンプレートを作成しました。

<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 は、別のものに変更/トグルした場合にのみ更新され、その後、予定が適切に表示されます。ユーザーが予定リストを表示する前に、別のものに切り替えてから元に戻す必要があるのは見苦しいので、自動化したいと思います。

4

2 に答える 2

3

Nick が示唆したように、INotifyPropertyChanged インターフェイスを使用することが重要です。

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

ObsCollection にプロパティの変更を認識させたい場合は、上記のリンクに表示されているように、このインターフェイスを実装する必要があります。これにより、何かが追加、削除、または変更されたときに、バインドされている UI コントロールが更新されます。それがなければ、実際にはコードの変更を追跡して手動で更新する必要があります。

実際、実装と使用は非常に簡単で、驚くほど素晴らしいものです。これを使用したくない場合は、単に winform を使用した方がよいでしょう。=)

お役に立てれば。

于 2012-06-13T18:16:51.323 に答える
1

Visibility の問題は、getで値を計算する読み取り専用プロパティにバインドされていることです。したがって、変更されたことを通知する方法はありません。

HasSchedule プロパティは、Appointment プロパティがいつ変更されるかを知る必要があります。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"));
}

これは、あなたが言ったように、ViewModel に INotifyPropertyChanged を実装したことを前提としています。この場合、コレクションが何らかの形で変更されるたびに、HasSchedule プロパティが変更されたことを通知します。バインディングは値を更新し、変更された場合は可視性を更新します。

于 2012-06-14T00:09:53.483 に答える