当 ObservableCollection 更改时 ItemsControl 不更新

Posted

技术标签:

【中文标题】当 ObservableCollection 更改时 ItemsControl 不更新【英文标题】:ItemsControl does not update when ObservableCollection changes 【发布时间】:2021-11-26 17:11:24 【问题描述】:

我正在创建一个日历并且我正在使用 MVVM 灯。当我更改可观察集合时,UI 不会更新。 我的目标是,如果我单击 ItemsControl 中的按钮,可观察的 Collection 会发生变化,并且应该在我的按钮样式中触发 DataTriger。

主窗口中的东西:

private ObservableCollection<Dates> _list;
public ObservableCollection<Dates> List
        
            get  return _list; 
            set
            
                _list = value;
                RaisePropertyChanged(nameof(List));
            
        

public RelayCommand<DateTime> DayClickedCommand  get; private set; 
private void DayClickedeCommandParameterhandling(DateTime s)
        
            for (int i = 0; i < List.Count; i++)
            
                if (List[i].Date == s)
                
                    List[i].IsSelected = true;
                
            
        

日期类:

public class Dates
    
        public Dates(DateTime day, int currentMonth)
        
            Date = day;
            Day = day.Day.ToString();
            if ((int)day.Month == currentMonth)
            
                IsInactive = false;
            
            else
            
                IsInactive = true;
            
            if (day.DayOfYear == DateTime.Today.DayOfYear)
            
                IsToday = true;
            
            else IsToday = false;
        

        #region Properties
        public DateTime Date  get; set; 
        public string Day  get; set; 
        public bool IsInactive  get; set; 
        public bool IsToday  get; set; 
        public bool IsSelected  get; set; 


        #endregion Properties
    

我的 Xaml:

 <ItemsControl ItemsSource="Binding List">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <WrapPanel></WrapPanel>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate >
                                <Grid Height="Binding ElementName=Monday, Path=ActualHeight" Width="Binding ElementName=Monday, Path=ActualWidth" Name="grid">
                                    <Button  Command="Binding RelativeSource=RelativeSource AncestorType=x:Type Window, Path=DataContext.DayClickedCommand" CommandParameter="Binding Date"  VerticalContentAlignment="Center" HorizontalContentAlignment="Center" MinHeight="10" MinWidth="10" FontSize="Binding ElementName=textblockMonday, Path=FontSize" Name="Button" BorderThickness="3" Content="Binding Day" >
                                            <Button.Style>
                                            <Style TargetType="Button">
                                                <Style.Triggers>
                                                    <DataTrigger Binding="Binding IsInactive" Value="True">
                                                        <Setter Property="Foreground" Value="Green" />
                                                        <Setter Property="Background" Value="Transparent" />
                                                    </DataTrigger> 
                                                    <DataTrigger Binding="Binding IsInactive" Value="false">
                                                        <Setter Property="Background" Value="Transparent" />
                                                    </DataTrigger>
                                                    <DataTrigger Binding="Binding IsToday" Value="true">
                                                        <Setter Property="Background" Value="Yellow" />
                                                        <Setter Property="Foreground" Value="Orange" />
                                                        <Setter Property="BorderBrush" Value="Orange" />
                                                    </DataTrigger> 
                                                    <DataTrigger Binding="Binding IsToday" Value="false">
                                                        <Setter Property="BorderBrush" Value="Transparent" />
                                                    </DataTrigger>
                                                    <DataTrigger Binding="Binding IsSelected" Value="true">
                                                        <Setter Property="Background" Value="Green" />
                                                        <Setter Property="Foreground" Value="Purple" />
                                                        <Setter Property="BorderBrush" Value="Orange" />
                                                    </DataTrigger>
                                                </Style.Triggers>
                                                </Style>
                                        </Button.Style>
                                    </Button>
                                </Grid>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>

命令运行,集合改变,但不通知ui。

【问题讨论】:

【参考方案1】:

您的Dates 类应该实现INotifyPropertyChanged 并为IsSelected 属性引发PropertyChanged 事件:

public class Dates : INotifyPropertyChanged

    public Dates(DateTime day, int currentMonth)
    
        Date = day;
        Day = day.Day.ToString();
        if ((int)day.Month == currentMonth)
        
            IsInactive = false;
        
        else
        
            IsInactive = true;
        
        if (day.DayOfYear == DateTime.Today.DayOfYear)
        
            IsToday = true;
        
        else IsToday = false;
    

    #region Properties
    public DateTime Date  get; set; 
    public string Day  get; set; 
    public bool IsInactive  get; set; 
    public bool IsToday  get; set; 

    private bool _isSelected;
    public bool IsSelected
    
        get  return _isSelected; 
        set  _isSelected = value; NotifyPropertyChanged(); 
    
    #endregion Properties

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]
        string propertyName = "")
    
        if (PropertyChanged != null)
        
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        
    

ObservableCollection&lt;T&gt; 中的 T 项目被修改时不会发出更改通知。仅当您向其中添加或删除项目时,它会引发一个事件。

【讨论】:

以上是关于当 ObservableCollection 更改时 ItemsControl 不更新的主要内容,如果未能解决你的问题,请参考以下文章

属性更改通知(INotifyPropertyChanged)——针对ObservableCollection

如何根据 WPF DataGrid 中的更改更新 ObservableCollection 项属性?

DataGrid单元格更改后,ObservableCollection不会更新

更改 ObservableCollection 时 Xamarin.Forms UWP (Windows) 应用程序中的 System.Runtime.InteropServices.COMExcep

当ObservableCollection发生变化时更新CollectionViewSource WP7

C# ObservableCollection和List的区别