WPF CALENDAR - ОСНОВНЫЕ ДАТЫ ОБЯЗАТЕЛЬСТВ - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь выделить даты цветом «LigthPink» для важных дат запланированных встреч. В моем проекте в WPF MVVM я создал код, но не могу обновить даты.

Я получил следующий код:

 class ConverterHigligthdate: IValueConverter
{
    static BindableCollection<DateTime> dict = new BindableCollection<DateTime>();

    public event PropertyChangedEventHandler PropertyChanged;

    static ConverterHigligthdate()
    {
        dict.Add(DateTime.Today);
        dict.Add(DateTime.Today.AddDays(2));
        dict.Add(DateTime.Today.AddDays(-10));
        dict.Add(DateTime.Today.AddDays(-20));
        dict.Add(DateTime.Today.AddDays(-15));
    }
    public static void AddDate(DateTime date)
    {
        dict.Add(date);
    }
    public static void RemoveDate(DateTime date)
    {
        dict.Remove(date);
    }
    public void Clear()
    {
        dict.Clear();
        dict.Refresh();
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string text = null;
        if (dict.Contains((DateTime)value))
            text = null;
        else
            text = "";

        return text;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

И в представлении:

 <Window.Resources>
    <local:ConverterHigligthdate x:Key="ConverterHigligthdate"/>
    <Style x:Key="calendarDayButtonStyle" TargetType="{x:Type CalendarDayButton}">
        <Setter Property="Margin" Value="8"/>
        <Setter Property="FontSize" Value="13"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Converter={StaticResource ConverterHigligthdate}}" Value="{x:Null}">
                <Setter Property="Background" Value="LightPink"/>                    
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid Margin="5">
        <Calendar SelectionMode="MultipleRange" CalendarDayButtonStyle="{DynamicResource calendarDayButtonStyle}"/>       
</Grid>

результат

Кто-нибудь знает, как реализовать то, что делает эту работу?

1 Ответ

1 голос
/ 28 апреля 2020

Вы идете об этом неправильно. С MVVM вы всегда ведете бизнес-логику c на уровне модели представления, а не в ваших конвертерах (они являются частью уровня представления).

Существует множество способов сделать это, но обычно вам нужно слой модели представления, чтобы подготовить ваши данные в формате, который представление может легко использовать. В целях производительности давайте обернем все выбранные вами даты в таблицу поиска:

public class MainViewModel
{
    public HashSet<DateTime> Dates { get; } = new HashSet<DateTime>();

    public MainViewModel()
    {
        // highlight today and tomorrow
        this.Dates.Add(DateTime.Today);
        this.Dates.Add(DateTime.Today.AddDays(1));
    }
}

Теперь в вашем CalendarDayButtonStyle вы хотите добавить DataTrigger. Когда дата соответствующей кнопки находится в вашей коллекции, тогда вы хотите изменить цвет фона:

    <Style x:Key="CalendarDayButtonStyle" TargetType="CalendarDayButton">
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource LookupConverter}">
                        <Binding />
                        <Binding Path="DataContext.Dates" RelativeSource="{RelativeSource AncestorType=Calendar}" />
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Background" Value="Pink" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

Итак, все, что вам сейчас нужно, - это конвертер для поиска. Нам нужно передать как таблицу поиска, так и значение для поиска, чтобы мы могли использовать MultiBinding. На самом деле это логика c, которую можно было бы поместить в модель представления, если бы мы действительно этого хотели, но она не ссылается на какие-либо данные, определенные моделью представления c, и ее можно повторно использовать в другом месте, поэтому мы Немного согну правила:

public class LookupConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var date = (DateTime)values[0];
        var dates = values[1] as HashSet<DateTime>;
        return dates.Contains(date);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

И это все, что вам нужно. Результат:

enter image description here

...