Reputation: 51
I am new in wpf and I am having quite a hard time trying to figure out how to notify a multiconverter that its binded collections have changed. I have tried several solutions but nothing works.
I have a calendar with a multiconverter allowing me to change calendardaybutton background according to 2 Observablecollection. (That woks, If I put data manually in the collections before datacontext is applied, I can see days are colored).
When user click on the calendar, the selected date is added to one of the collections.
I have checked, the new date is correctly added to the collection, but I don't see any change on the calendar (the clicked calendardaybutton background should change).
Here is my XAML:
<Window.Resources>
<local:DateConverter x:Key="dateConverter" />
<local:MyViewModel x:Key="myViewModel" />
</Window.Resources>
<Grid>
<Calendar x:Name="MyCal"
SelectionMode="MultipleRange"
SelectedDatesChanged="OnSelectedDatesChanged">
<Calendar.CalendarDayButtonStyle>
<Style TargetType="CalendarDayButton">
<Setter Property="Background" >
<Setter.Value>
<MultiBinding Converter="{StaticResource dateConverter}">
<Binding/>
<Binding Source="{StaticResource myViewModel}" Path="MyHolidayCollection" UpdateSourceTrigger="PropertyChanged"/>
<Binding Source="{StaticResource myViewModel}" Path="ShutDownDateCollection" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Calendar.CalendarDayButtonStyle>
</Calendar>
</Grid>`
My DataContext is a ViewModel containing the 2 observable collections
public partial class MainWindow : Window
{
MyViewModel myViewModel;
public MainWindow()
{
myViewModel = new MyViewModel();
DataContext = myViewModel;
InitializeComponent();
}
private void OnSelectedDatesChanged(object sender, RoutedEventArgs e)
{
Calendar c = (Calendar)sender;
myViewModel.AssignDate(c.SelectedDate);
}
}
Here is my ViewModel (inherited from ViewModelBase, implementing INotifyPropertyChanged)
public class MyViewModel:ViewModelBase
{
private ObservableCollection<DateTime?> _holidayDateCollection;
public ObservableCollection<DateTime?> HolidayDateCollection
{
get { return _holidayDateCollection; }
set
{
_holidayDateCollection = value;
OnPropertyChanged("HolidayDateCollection");
}
}
private ObservableCollection<DateTime?> _shutDownDateCollection;
public ObservableCollection<DateTime?> ShutDownDateCollection
{
get { return _holidayDateCollection; }
set
{
_holidayDateCollection = value;
OnPropertyChanged("ShutDownDateCollection");
}
}
public MyViewModel()
{
HolidayDateCollection = new ObservableCollection<DateTime?>();
ShutDownDateCollection = new ObservableCollection<DateTime?>();
}
public void AssignDate(DateTime? date)
{
HolidayDateCollection.Add(date);
}
And here is my multiconverter
public class DateConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
SolidColorBrush s = new SolidColorBrush(Colors.LightBlue);
SolidColorBrush s1 = new SolidColorBrush(Colors.Yellow);
SolidColorBrush s2 = new SolidColorBrush(Colors.Red);
if (((ObservableCollection<DateTime?>)values[1]).Contains((DateTime?)values[0])) { return s1; }
if (((ObservableCollection<DateTime?>)values[2]).Contains((DateTime?)values[0])) { return s2; }
return s;//normal day
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException("Cannot convert back");
}
}
I tried a lot of solutions (that I removed to clear the code here) but nothing seems to works.
Any help or advise would be much appreciated, i am stuck for days now. Thank you.
Upvotes: 1
Views: 267
Reputation: 26085
You are referencing two completely different ViewModel
instances which is why you are facing the issue.
Instance 1: (inside xaml)
<Window.Resources>
<local:DateConverter x:Key="dateConverter" />
<local:MyViewModel x:Key="myViewModel" />
</Window.Resources>
Instance 2: (in your code behind file)
myViewModel = new MyViewModel();
DataContext = myViewModel;
To fix the issue, change MyViewModel
instance from either one. For example, after removing form xaml your code will look like:
<Window.Resources>
<local:DateConverter x:Key="dateConverter" />
</Window.Resources>
<Grid>
<Calendar x:Name="MyCal"
SelectionMode="MultipleRange"
SelectedDatesChanged="OnSelectedDatesChanged">
<Calendar.CalendarDayButtonStyle>
<Style TargetType="CalendarDayButton">
<Setter Property="Background" >
<Setter.Value>
<MultiBinding Converter="{StaticResource dateConverter}">
<Binding />
<Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="DataContext.HolidayDateCollection" UpdateSourceTrigger="PropertyChanged"/>
<Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="DataContext.ShutDownDateCollection" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Calendar.CalendarDayButtonStyle>
</Calendar>
</Grid>
Upvotes: 3