WPF уведомляет MultiConverter об изменении связанной коллекции - PullRequest
0 голосов
/ 03 сентября 2018

Я новичок в wpf, и мне довольно трудно пытаться выяснить, как уведомить мультиконвертер об изменении его связанных коллекций. Я пробовал несколько решений, но ничего не работает.

У меня есть календарь с мультиконвертером, позволяющий мне изменять фон календаря для кнопки в соответствии с 2 Observablecollection. (Вот и все, если я помещу данные вручную в коллекции до применения текстового текста, я вижу, что дни окрашены).

Когда пользователь нажимает на календарь, выбранная дата добавляется в одну из коллекций.

Я проверил, новая дата правильно добавлена ​​в коллекцию, но я не вижу никаких изменений в календаре (фон кнопки calendardaybutton, на который нажали, должен измениться).

Вот мой 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 - это модель представления, содержащая 2 наблюдаемые коллекции

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

Вот мой ViewModel (унаследованный от ViewModelBase, реализующий 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);
    }

А вот и мой мультиконвертер

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

Я пробовал много решений (которые я удалил, чтобы очистить код здесь), но, похоже, ничего не работает.

Буду очень признателен за любую помощь или совет, я застрял на несколько дней. Спасибо.

1 Ответ

0 голосов
/ 03 сентября 2018

Вы ссылаетесь на два совершенно разных экземпляра ViewModel, поэтому вы столкнулись с проблемой.

Экземпляр 1: (внутри xaml)

<Window.Resources>
    <local:DateConverter x:Key="dateConverter" />
    <local:MyViewModel x:Key="myViewModel" />
</Window.Resources>

Экземпляр 2: (в вашем коде за файлом)

myViewModel = new MyViewModel();
DataContext = myViewModel;

Чтобы устранить проблему, измените экземпляр MyViewModel с любого из них. Например, после удаления формы xaml ваш код будет выглядеть так:

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