Home > Mobile >  ItemsControl does not update when ObservableCollection changes
ItemsControl does not update when ObservableCollection changes

Time:10-07

I am creating a calendar and I am using MVVM light. When i change the observable Collection the UI is not updated. My goal is if i click on a button in my ItemsControl the observable Collection changes and should trigger the DataTriger in my buttonstyle.

Things from MainWindow:

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

Dates class:

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
    }

My 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>

The command is working and the collection is changed, but the ui is not informed.

CodePudding user response:

Your Dates class should implement INotifyPropertyChanged and raise the PropertyChanged event for the IsSelected property:

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

An ObservableCollection<T> doesn't raise change notifications when the T items in it are modified. It raises an event when you add or remove items to and from it only.

  • Related