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.