2016-08-02 132 views
1

我有一個模型:實施IsDirty在WPF MVVM觀察集合

namespace CCBDPlayer.Models 
{ 
public class Schedule : DependencyObject, IEquatable<Schedule>, INotifyPropertyChanged 
{ 
    private DateTime _scheduledStart; 
    private DateTime _scheduledEnd; 
    private bool _enabled; 
    private string _url; 
    private bool _isDirty; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public Schedule() { } 

    public static readonly DependencyProperty IsDirtyProperty = 
     DependencyProperty.Register("IsDirty", typeof(Boolean),typeof(Schedule)); 
    public DateTime ScheduledStart 
    { 
     get { return _scheduledStart; } 
     set 
     { 
      _scheduledStart = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("ScheduledStart")); 
     } 
    } 
    public DateTime ScheduledEnd 
    { 
     get { return _scheduledEnd; } 
     set 
     { 
      if (value < ScheduledStart) 
      { 
       throw new ArgumentException("Scheduled End cannot be earlier than Scheduled Start."); 
      } 
      else 
      { 
       _scheduledEnd = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("ScheduledEnd")); 
      } 
     } 
    } 
    public bool Enabled 
    { 
     get { return _enabled; } 
     set 
     { 
      _enabled = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("Enabled")); 
      IsDirty = true; 
     } 
    } 
    public string Url 
    { 
     get { return _url; } 
     set 
     { 
      _url = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("Url")); 
      IsDirty = true; 
     } 
    } 

    [XmlIgnoreAttribute] 
    public bool IsDirty 
    { 
     get { return (bool)GetValue(IsDirtyProperty); } 
     set { SetValue(IsDirtyProperty, value); } 
    } 

    public bool Equals(Schedule other) 
    { 
     if(this.ScheduledStart == other.ScheduledStart && this.ScheduledEnd == other.ScheduledEnd 
      && this.Enabled == other.Enabled && this.Url == other.Url) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    public void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 
} 

}

這個模型是存在於我的ViewModel一個ObservableCollection使用。該的ObservableCollection綁定到一個ItemsControl在我看來:

  <ItemsControl ItemsSource="{Binding Config.Schedules}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Border x:Name="ScheduleBorder" BorderBrush="Black" BorderThickness="1" Margin="5,5" VerticalAlignment="Top"> 
         <Grid VerticalAlignment="Top"> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="4*" /> 
           <RowDefinition Height="2*" /> 
          </Grid.RowDefinitions> 
          <Grid Grid.Row="0"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="2*" /> 
            <ColumnDefinition Width="3*" /> 
            <ColumnDefinition Width="1*" /> 
           </Grid.ColumnDefinitions> 
           <Grid.RowDefinitions> 
            <RowDefinition /> 
            <RowDefinition /> 
            <RowDefinition /> 
           </Grid.RowDefinitions> 
           <Label Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Content="Scheduled Start" VerticalAlignment="Top"/> 
           <xctk:DateTimePicker Grid.Column="1" Grid.Row="0" Value="{Binding ScheduledStart}" Margin="0,2" VerticalAlignment="Center" /> 
           <Label Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" Content="Scheduled End" /> 
           <xctk:DateTimePicker Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Value="{Binding ScheduledEnd}" Margin="0.2" /> 
           <Button Grid.Row="0" Grid.Column="2" Margin="5,5" Background="White" VerticalAlignment="Top" Width="15" Height="15" 
             Command="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.RemoveScheduleCommand}" CommandParameter="{Binding}"> 
            <Image Source="Images/delete-button.png"/> 
           </Button> 
           <Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Left" Content="Url" VerticalAlignment="Top"/> 
           <TextBox Grid.Column="1" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Url}" Width="Auto"/> 
          </Grid> 
          <Grid Grid.Row="1"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="3*"/> 
            <ColumnDefinition Width="1*" /> 
           </Grid.ColumnDefinitions> 
           <CheckBox Content="Enable" Margin="5" IsChecked="{Binding Enabled}"/> 
           <Button Grid.Column="1" HorizontalAlignment="Right" Width="65" Content="Save" Margin="0, 2"/> 
          </Grid> 
         </Grid> 
        </Border> 
        <DataTemplate.Triggers> 
         <DataTrigger Binding="{Binding Path=IsDirty}" Value="true"> 
          <Setter Property="Background" TargetName="ScheduleBorder" Value="Yellow"/> 
         </DataTrigger> 
        </DataTemplate.Triggers> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 

我需要可以設置IsDirty只有在模型實例的初始化。有什麼建議?

UPDATE

我有DataTrigger到模板的背景設置爲黃色,如果該實例是「髒」。現在,如果我只是將 IsDirty = true 添加到屬性設置器,那麼模板將始終具有黃色背景。我需要一種方法讓模型忽略屬性上的第一初始化值。

+0

我可能是錯的,但要綁定那個東西,它已經必須實例化了,必須嗎?因此,也許更準確地解釋你的自我 – lokusking

+0

加載Config.Schedules後,爲什麼不重置它? foreach(在Config.Schedules中調度var)sched.IsDirty = false;如果你真的不希望IsDirty被設置爲true,那麼可以將IsDirty更改爲可爲空的布爾值,並且如果IsDirty爲null,則不要在屬性設置器中更新IsDirty。您仍然必須在某個時間點設置IsDirty = false來表示您希望IsDirty現在在屬性設置器中更新。 –

+0

便宜又髒,使用加載後設置的bool標誌。沒有「解決方案」。 – Will

回答

0

加載完Config.Schedules之後,爲什麼不重置它?

foreach (var sched in Config.Schedules) 
    sched.IsDirty = false; 

如果你真的不想IsDirty永遠被設置爲true,那麼也許改變IsDirty爲可空布爾如果IsDirty爲null不要在屬性setter更新IsDirty。您仍然必須在某個時刻設置IsDirty = false來表示您希望IsDirty現在在屬性設置器中更新

+0

感謝您的回答。我添加了一個對Window_Loaded事件的foreach。很棒。 –