Search code examples
xamlcalendarwinui-3winui

How to add a list in this calendarview to a specific date?


I am working in a calender application in winui and need to add a list on a specific date

I have tried adding a text block and next I would like to change it to a list


Solution

  • You can create a user control like this one:

    CustomCalendarView.xaml

    <UserControl
        x:Class="CalendarViewTests.CustomCalendarView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="using:CalendarViewTests"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid>
            <CalendarView
                x:Name="CalendarViewControl"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                CalendarItemBorderBrush="DimGray"
                CalendarItemBorderThickness="1"
                CalendarItemCornerRadius="0"
                DayItemFontSize="10"
                DayItemFontWeight="ExtraLight"
                HorizontalDayItemAlignment="Center"
                VerticalDayItemAlignment="Top">
                <CalendarView.CalendarViewDayItemStyle>
                    <Style TargetType="CalendarViewDayItem">
                        <Setter Property="FontSize" Value="10" />
                        <Setter Property="FontWeight" Value="ExtraLight" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Grid
                                        Margin="5"
                                        VerticalAlignment="Center">
                                        <ListView ItemsSource="{Binding}" />
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </CalendarView.CalendarViewDayItemStyle>
            </CalendarView>
        </Grid>
    </UserControl>
    

    CustomCalenderView.xaml.cs

    using Microsoft.UI.Xaml;
    using Microsoft.UI.Xaml.Controls;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace CalendarViewTests;
    
    public record CustomCalendarViewDayItem
    {
        public CustomCalendarViewDayItem(DateTime dateTime, string text)
        {
            DateTime = dateTime;
            Text = text;
        }
    
        public DateTime DateTime { get; }
    
        public string Text { get; }
    }
    
    public sealed partial class CustomCalendarView : UserControl
    {
        public static readonly DependencyProperty DayItemsProperty = DependencyProperty.Register(
            nameof(DayItems),
            typeof(IEnumerable<CustomCalendarViewDayItem>),
            typeof(CustomCalendarView),
            new PropertyMetadata(default));
    
        public CustomCalendarView()
        {
            InitializeComponent();
            this.CalendarViewControl.CalendarViewDayItemChanging += CalendarViewControl_CalendarViewDayItemChanging;
        }
    
        public IEnumerable<CustomCalendarViewDayItem> DayItems
        {
            get => (IEnumerable<CustomCalendarViewDayItem>)GetValue(DayItemsProperty);
            set => SetValue(DayItemsProperty, value);
        }
    
        private void CalendarViewControl_CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args)
        {
            if (DayItems.Where(x => DateOnly.FromDateTime(x.DateTime) == DateOnly.FromDateTime(args.Item.Date.Date))
                .Select(x => x.Text) is IEnumerable<string> dayItems)
            {
                args.Item.DataContext = dayItems;
            }
        }
    }
    

    and use it like this:

    MainPage.xaml

    <Page
        x:Class="CalendarViewTests.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="using:CalendarViewTests"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
        mc:Ignorable="d">
    
        <Grid>
            <local:CustomCalendarView DayItems="{x:Bind DayItems, Mode=OneWay}" />
        </Grid>
    </Page>
    

    MainPage.xaml.cs

    using Microsoft.UI.Xaml.Controls;
    using System;
    using System.Collections.ObjectModel;
    
    namespace CalendarViewTests;
    
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now.AddDays(-5), "5 days ago"));
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now, "Todo 1"));
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now, "Todo 2"));
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now, "Todo 3"));
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now, "Todo 4"));
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now, "Todo 5"));
            DayItems.Add(new CustomCalendarViewDayItem(DateTime.Now.AddDays(1), "Tommorrow"));
        }
    
        public ObservableCollection<CustomCalendarViewDayItem> DayItems { get; } = new();
    }