none
xamlで配列したものをcsファイルでどのように扱うのか分かりません。(WPF xaml C#) RRS feed

  • 質問

  • WPF xamlを初めてはみたのですが、Bindingでつまづいている感じです。
    今回は自作カレンダーを作りました。質問タイトルの通り、xamlで宣言した配列をcsファイル中で扱うにはどのようにしたら良いのか分からず質問しております。自作カレンダーは一応希望通りの動きはするのですが、コードとしてはベタベタ感があり、WPFの肝であるBindを使ってみたいと考えた次第です。色々調べてはいるのですが、とうとう此処でお世話になる時だと思った次第です。

    コードは以下の通りです。

    xaml

    <Window x:Class="WPFCalendarAlpha.MainWindow"
            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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPFCalendarAlpha"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="450" Loaded="Window_Loaded">
        <Window.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="TextAlignment" Value="Center"/>
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="Margin" Value="2"/>
            </Style>
        </Window.Resources>
        <Grid>
            <Grid x:Name="GridCalendar" Grid.Row="1" Grid.Column="0" Grid.RowSpan="1" Margin="10,10,10,10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
    
                <Button x:Name="BtnPrev" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Width="80" Height="40" Content="PREV MONTH" FontSize="10" Background="White"  Click="BtnPrev_Click"/>
                <TextBlock x:Name="txblkMonth" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="3" Text="XXXX/MM" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <Button x:Name="BtnNext" Grid.Column="5" Grid.Row="0" Grid.ColumnSpan="2" Width="80" Height="40" Content="NEXT MONTH" FontSize="10" Background="White" Click="BtnNext_Click"/>
    
                <TextBlock  x:Name = "su"  Grid.Column="0" Grid.Row="1" Text="Sun" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "mo"  Grid.Column="1" Grid.Row="1" Text="Mon"/>
                <TextBlock  x:Name = "tu"  Grid.Column="2" Grid.Row="1" Text="Tue"/>
                <TextBlock  x:Name = "we"  Grid.Column="3" Grid.Row="1" Text="Wed"/>
                <TextBlock  x:Name = "th"  Grid.Column="4" Grid.Row="1" Text="Thu"/>
                <TextBlock  x:Name = "fr"  Grid.Column="5" Grid.Row="1" Text="Fri"/>
                <TextBlock  x:Name = "sa"  Grid.Column="6" Grid.Row="1" Text="Sat" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d0"  Grid.Column="0" Grid.Row="2" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d1"  Grid.Column="1" Grid.Row="2" />
                <TextBlock  x:Name = "d2"  Grid.Column="2" Grid.Row="2" />
                <TextBlock  x:Name = "d3"  Grid.Column="3" Grid.Row="2" />
                <TextBlock  x:Name = "d4"  Grid.Column="4" Grid.Row="2" />
                <TextBlock  x:Name = "d5"  Grid.Column="5" Grid.Row="2" />
                <TextBlock  x:Name = "d6"  Grid.Column="6" Grid.Row="2" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d7"  Grid.Column="0" Grid.Row="3" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d8"  Grid.Column="1" Grid.Row="3" />
                <TextBlock  x:Name = "d9"  Grid.Column="2" Grid.Row="3" />
                <TextBlock  x:Name = "d10" Grid.Column="3" Grid.Row="3" />
                <TextBlock  x:Name = "d11" Grid.Column="4" Grid.Row="3" />
                <TextBlock  x:Name = "d12" Grid.Column="5" Grid.Row="3" />
                <TextBlock  x:Name = "d13" Grid.Column="6" Grid.Row="3" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d14" Grid.Column="0" Grid.Row="4" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d15" Grid.Column="1" Grid.Row="4" />
                <TextBlock  x:Name = "d16" Grid.Column="2" Grid.Row="4" />
                <TextBlock  x:Name = "d17" Grid.Column="3" Grid.Row="4" />
                <TextBlock  x:Name = "d18" Grid.Column="4" Grid.Row="4" />
                <TextBlock  x:Name = "d19" Grid.Column="5" Grid.Row="4" />
                <TextBlock  x:Name = "d20" Grid.Column="6" Grid.Row="4" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d21" Grid.Column="0" Grid.Row="5" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d22" Grid.Column="1" Grid.Row="5" />
                <TextBlock  x:Name = "d23" Grid.Column="2" Grid.Row="5" />
                <TextBlock  x:Name = "d24" Grid.Column="3" Grid.Row="5" />
                <TextBlock  x:Name = "d25" Grid.Column="4" Grid.Row="5" />
                <TextBlock  x:Name = "d26" Grid.Column="5" Grid.Row="5" />
                <TextBlock  x:Name = "d27" Grid.Column="6" Grid.Row="5" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d28" Grid.Column="0" Grid.Row="6" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d29" Grid.Column="1" Grid.Row="6" />
                <TextBlock  x:Name = "d30" Grid.Column="2" Grid.Row="6" />
                <TextBlock  x:Name = "d31" Grid.Column="3" Grid.Row="6" />
                <TextBlock  x:Name = "d32" Grid.Column="4" Grid.Row="6" />
                <TextBlock  x:Name = "d33" Grid.Column="5" Grid.Row="6" />
                <TextBlock  x:Name = "d34" Grid.Column="6" Grid.Row="6" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d35" Grid.Column="0" Grid.Row="7" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d36" Grid.Column="1" Grid.Row="7" />
            </Grid>
        </Grid>
    </Window>

    cs

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace WPFCalendarAlpha
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            // 今日の日付 Date of Today
            readonly DateTime dateOfToday = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);
    
            // 月初めの曜日 Day of week of 1st day of the month
            readonly DateTime firstDayOfWeek = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
    
            // TextBlock配列 Array of TextBlock
            public TextBlock[] txblk = new TextBlock[37];
    
            private void Window_Loaded(object sender, RoutedEventArgs e) // Window_Loaded Event Property
            {
    
                txblkMonth.Text = dateOfToday.ToString("yyyy / M");
    
                txblk[0] = d0; txblk[10] = d10; txblk[20] = d20; txblk[30] = d30;
                txblk[1] = d1; txblk[11] = d11; txblk[21] = d21; txblk[31] = d31;
                txblk[2] = d2; txblk[12] = d12; txblk[22] = d22; txblk[32] = d32;
                txblk[3] = d3; txblk[13] = d13; txblk[23] = d23; txblk[33] = d33;
                txblk[4] = d4; txblk[14] = d14; txblk[24] = d24; txblk[34] = d34;
                txblk[5] = d5; txblk[15] = d15; txblk[25] = d25; txblk[35] = d35;
                txblk[6] = d6; txblk[16] = d16; txblk[26] = d26; txblk[36] = d36;
                txblk[7] = d7; txblk[17] = d17; txblk[27] = d27;
                txblk[8] = d8; txblk[18] = d18; txblk[28] = d28;
                txblk[9] = d9; txblk[19] = d19; txblk[29] = d29;
    
                CreateCalendar(firstDayOfWeek);
            }
    
            private void CreateCalendar(DateTime date)
            {
                //カレンダーの日付をクリアにする Clear of Days of Calendar
                for (int i = 0; i < 37; i++)
                {
                    txblk[i].Text = "";
                }
                //月初めの曜日からカレンダーを作る Check day of week and create calendar
                switch (date.DayOfWeek)
                {
                    case DayOfWeek.Sunday:
                        for (int d = 0; d < DateTime.DaysInMonth(date.Year, date.Month); d++)
                        {
                            txblk[d].Text = (d + 1).ToString();
                        }
                        break;
                    case DayOfWeek.Monday:
                        for (int d = 1; d < DateTime.DaysInMonth(date.Year, date.Month) + 1; d++)
                        {
                            txblk[d].Text = d.ToString();
                        }
                        break;
                    case DayOfWeek.Tuesday:
                        for (int d = 2; d < DateTime.DaysInMonth(date.Year, date.Month) + 2; d++)
                        {
                            txblk[d].Text = (d - 1).ToString();
                        }
                        break;
                    case DayOfWeek.Wednesday:
                        for (int d = 3; d < DateTime.DaysInMonth(date.Year, date.Month) + 3; d++)
                        {
                            txblk[d].Text = (d - 2).ToString();
                        }
                        break;
                    case DayOfWeek.Thursday:
                        for (int d = 4; d < DateTime.DaysInMonth(date.Year, date.Month) + 4; d++)
                        {
                            txblk[d].Text = (d - 3).ToString();
                        }
                        break;
                    case DayOfWeek.Friday:
                        for (int d = 5; d < DateTime.DaysInMonth(date.Year, date.Month) + 5; d++)
                        {
                            txblk[d].Text = (d - 4).ToString();
                        }
                        break;
                    case DayOfWeek.Saturday:
                        for (int d = 6; d < DateTime.DaysInMonth(date.Year, date.Month) + 6; d++)
                        {
                            txblk[d].Text = (d - 5).ToString();
                        }
                        break;
                }
            }
    
            private void BtnPrev_Click(object sender, RoutedEventArgs e)
            {
                //表示月から1ヶ月引く substract a month from indicated month on the txblkMonth
                DateTime prevMonth = DateTime.ParseExact(txblkMonth.Text, "yyyy / M", null).AddMonths(-1);
    
                txblkMonth.Text = prevMonth.ToString("yyyy / M");
                CreateCalendar(prevMonth);
            }
    
            private void BtnNext_Click(object sender, RoutedEventArgs e)
            {
                //表示月に1ヶ月足す add a month to indicated month on the txblkMonth
                DateTime NextMonth = DateTime.ParseExact(txblkMonth.Text, "yyyy / M", null).AddMonths(+1);
    
                txblkMonth.Text = NextMonth.ToString("yyyy / M");
                CreateCalendar(NextMonth);
            }
        }
    }

    今回のコードではbindをどのように使うかが分からず、csコードの中にTextBlockの配列を宣言して、xamlで宣言したx:Nameをリンクさせるようにしました。Bindを使う時のコードは Text="{Binding Path=....[1]}"と書けば良いということまでは調べられたのですが、csファイル中でそれを扱う方法が分からなかったのでご教授頂ければ幸いです。

    その他、このコード全般に関してアドバイスを頂けると嬉しいです。

    2020年7月29日 13:22

回答

  • 日付に関するデータ作ってXAML側に渡します

    <Window x:Class="WPFCalendarAlpha.MainWindow"
             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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPFCalendarAlpha"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
        <Window.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="TextAlignment" Value="Center"/>
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="Margin" Value="2"/>
            </Style>
        </Window.Resources>
        <UniformGrid Columns="2" Rows="1">
    
            <!-- 提示されたコードを生かしたバインディング-->
            <Grid x:Name="GridCalendar" Grid.Row="1" Grid.Column="0" Grid.RowSpan="1" Margin="10,10,10,10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
    
                <Button x:Name="BtnPrev" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Width="80" Height="40" Content="PREV MONTH" FontSize="10" Background="White"  Click="BtnPrev_Click"/>
                <TextBlock x:Name="txblkMonth" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="3" Text="XXXX/MM" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <Button x:Name="BtnNext" Grid.Column="5" Grid.Row="0" Grid.ColumnSpan="2" Width="80" Height="40" Content="NEXT MONTH" FontSize="10" Background="White" Click="BtnNext_Click"/>
    
                <TextBlock  x:Name = "su"  Grid.Column="0" Grid.Row="1" Text="Sun" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "mo"  Grid.Column="1" Grid.Row="1" Text="Mon"/>
                <TextBlock  x:Name = "tu"  Grid.Column="2" Grid.Row="1" Text="Tue"/>
                <TextBlock  x:Name = "we"  Grid.Column="3" Grid.Row="1" Text="Wed"/>
                <TextBlock  x:Name = "th"  Grid.Column="4" Grid.Row="1" Text="Thu"/>
                <TextBlock  x:Name = "fr"  Grid.Column="5" Grid.Row="1" Text="Fri"/>
                <TextBlock  x:Name = "sa"  Grid.Column="6" Grid.Row="1" Text="Sat" Foreground="DodgerBlue"/>
    
                <!-- DataContextに設定したmodelのDisplayDatesコレクションのインデックスでバインディング-->
                <TextBlock  x:Name = "d0"  Grid.Column="0" Grid.Row="2" Text="{Binding Path=DisplayDates[0].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d1"  Grid.Column="1" Grid.Row="2" Text="{Binding Path=DisplayDates[1].Day}"/>
                <TextBlock  x:Name = "d2"  Grid.Column="2" Grid.Row="2" Text="{Binding Path=DisplayDates[2].Day}"/>
                <TextBlock  x:Name = "d3"  Grid.Column="3" Grid.Row="2" Text="{Binding Path=DisplayDates[3].Day}"/>
                <TextBlock  x:Name = "d4"  Grid.Column="4" Grid.Row="2" Text="{Binding Path=DisplayDates[4].Day}"/>
                <TextBlock  x:Name = "d5"  Grid.Column="5" Grid.Row="2" Text="{Binding Path=DisplayDates[5].Day}"/>
                <TextBlock  x:Name = "d6"  Grid.Column="6" Grid.Row="2" Text="{Binding Path=DisplayDates[6].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d7"  Grid.Column="0" Grid.Row="3" Text="{Binding Path=DisplayDates[7].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d8"  Grid.Column="1" Grid.Row="3" Text="{Binding Path=DisplayDates[8].Day}" />
                <TextBlock  x:Name = "d9"  Grid.Column="2" Grid.Row="3" Text="{Binding Path=DisplayDates[9].Day}" />
                <TextBlock  x:Name = "d10" Grid.Column="3" Grid.Row="3" Text="{Binding Path=DisplayDates[10].Day}" />
                <TextBlock  x:Name = "d11" Grid.Column="4" Grid.Row="3" Text="{Binding Path=DisplayDates[11].Day}" />
                <TextBlock  x:Name = "d12" Grid.Column="5" Grid.Row="3" Text="{Binding Path=DisplayDates[12].Day}" />
                <TextBlock  x:Name = "d13" Grid.Column="6" Grid.Row="3" Text="{Binding Path=DisplayDates[13].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d14" Grid.Column="0" Grid.Row="4" Text="{Binding Path=DisplayDates[14].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d15" Grid.Column="1" Grid.Row="4" Text="{Binding Path=DisplayDates[15].Day}" />
                <TextBlock  x:Name = "d16" Grid.Column="2" Grid.Row="4" Text="{Binding Path=DisplayDates[16].Day}" />
                <TextBlock  x:Name = "d17" Grid.Column="3" Grid.Row="4" Text="{Binding Path=DisplayDates[17].Day}" />
                <TextBlock  x:Name = "d18" Grid.Column="4" Grid.Row="4" Text="{Binding Path=DisplayDates[18].Day}" />
                <TextBlock  x:Name = "d19" Grid.Column="5" Grid.Row="4" Text="{Binding Path=DisplayDates[19].Day}" />
                <TextBlock  x:Name = "d20" Grid.Column="6" Grid.Row="4" Text="{Binding Path=DisplayDates[20].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d21" Grid.Column="0" Grid.Row="5" Text="{Binding Path=DisplayDates[21].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d22" Grid.Column="1" Grid.Row="5" Text="{Binding Path=DisplayDates[22].Day}" />
                <TextBlock  x:Name = "d23" Grid.Column="2" Grid.Row="5" Text="{Binding Path=DisplayDates[23].Day}" />
                <TextBlock  x:Name = "d24" Grid.Column="3" Grid.Row="5" Text="{Binding Path=DisplayDates[24].Day}" />
                <TextBlock  x:Name = "d25" Grid.Column="4" Grid.Row="5" Text="{Binding Path=DisplayDates[25].Day}" />
                <TextBlock  x:Name = "d26" Grid.Column="5" Grid.Row="5" Text="{Binding Path=DisplayDates[26].Day}" />
                <TextBlock  x:Name = "d27" Grid.Column="6" Grid.Row="5" Text="{Binding Path=DisplayDates[27].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d28" Grid.Column="0" Grid.Row="6" Text="{Binding Path=DisplayDates[28].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d29" Grid.Column="1" Grid.Row="6" Text="{Binding Path=DisplayDates[29].Day}" />
                <TextBlock  x:Name = "d30" Grid.Column="2" Grid.Row="6" Text="{Binding Path=DisplayDates[30].Day}" />
                <TextBlock  x:Name = "d31" Grid.Column="3" Grid.Row="6" Text="{Binding Path=DisplayDates[31].Day}" />
                <TextBlock  x:Name = "d32" Grid.Column="4" Grid.Row="6" Text="{Binding Path=DisplayDates[32].Day}" />
                <TextBlock  x:Name = "d33" Grid.Column="5" Grid.Row="6" Text="{Binding Path=DisplayDates[33].Day}" />
                <TextBlock  x:Name = "d34" Grid.Column="6" Grid.Row="6" Text="{Binding Path=DisplayDates[34].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d35" Grid.Column="0" Grid.Row="7" Text="{Binding Path=DisplayDates[35].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d36" Grid.Column="1" Grid.Row="7" Text="{Binding Path=DisplayDates[36].Day}" />
            </Grid>
    
    
            <!-- よりWPFらしいバインディング -->
            <DockPanel>
                <ItemsControl DockPanel.Dock="Top" ItemsSource="{Binding DayOfWeeks}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid Columns="7" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
    
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="t" Text="{Binding Path=.}" 
                                       FontSize="20" Margin="2" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding Path=.}" Value="Sunday">
                                    <Setter TargetName="t" Property="Foreground" Value="OrangeRed"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Path=.}" Value="Saturday">
                                    <Setter TargetName="t" Property="Foreground" Value="DodgerBlue"/>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
    
                <ListBox ItemsSource="{Binding Path=DisplayDates}"
                         BorderThickness="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
                         SelectedItem="{ Binding CurrentDay}">
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid Columns="7" />
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                    
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="t" Text="{Binding Path=Day}" 
                                       FontSize="20" Margin="2" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding Path=DayOfWeek}" Value="Sunday">
                                    <Setter TargetName="t" Property="Foreground" Value="OrangeRed"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Path=DayOfWeek}" Value="Saturday">
                                    <Setter TargetName="t" Property="Foreground" Value="DodgerBlue"/>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DockPanel>
        </UniformGrid>
    </Window>
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    
    namespace WPFCalendarAlpha
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = model;
            }
    
            private Model model = new Model();
    
            private void Window_Loaded(object sender, RoutedEventArgs e) // Window_Loaded Event Property
            {
            }
    
            private void BtnPrev_Click(object sender, RoutedEventArgs e)
            {
                //表示月から1ヶ月引く substract a month from indicated month on the txblkMonth
                model.CreateCalendar(model.FirstDay.AddMonths(-1));
            }
    
            private void BtnNext_Click(object sender, RoutedEventArgs e)
            {
                //表示月に1ヶ月足す add a month to indicated month on the txblkMonth
                model.CreateCalendar(model.FirstDay.AddMonths(+1));
            }
        }
    
        class Model : System.ComponentModel.INotifyPropertyChanged
        {
            public Model()
            {
                CreateCalendar(this.CurrentDay);
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string name)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
    
            public DayOfWeek[] DayOfWeeks => (DayOfWeek[])Enum.GetValues(typeof(DayOfWeek));
    
            public ObservableCollection<DateTime?> DisplayDates { get; }
                = new ObservableCollection<DateTime?>(new DateTime?[37]);//大きさを37で初期化しているだけです
    
            public DateTime FirstDay
            {
                get
                {
                    return _FirstDay;
                }
                set
                {
                    _FirstDay = value;
                    OnPropertyChanged(nameof(FirstDay));
                }
            }
            private DateTime _FirstDay;
    
            public DateTime CurrentDay
            {
                get
                {
                    return _CurrentDay;
                }
                set
                {
                    _CurrentDay = value;
                    OnPropertyChanged(nameof(CurrentDay));
                }
            }
            private DateTime _CurrentDay = DateTime.Today;
    
            public void CreateCalendar(DateTime date)
            {
                this.FirstDay = new DateTime(date.Year, date.Month, 1);
                int diff = -(int)FirstDay.DayOfWeek;
    
                DateTime d = FirstDay.AddDays(diff);
                for (int i = 0; i < 37; i++)
                {
                    DisplayDates[i] = d;
                    d = d.AddDays(1);
                }
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2020年7月30日 0:08 貼り付け失敗
    • 回答としてマーク SuperBeginner 2020年7月30日 11:27
    2020年7月29日 22:54

すべての返信

  • 日付に関するデータ作ってXAML側に渡します

    <Window x:Class="WPFCalendarAlpha.MainWindow"
             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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPFCalendarAlpha"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
        <Window.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="TextAlignment" Value="Center"/>
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="Margin" Value="2"/>
            </Style>
        </Window.Resources>
        <UniformGrid Columns="2" Rows="1">
    
            <!-- 提示されたコードを生かしたバインディング-->
            <Grid x:Name="GridCalendar" Grid.Row="1" Grid.Column="0" Grid.RowSpan="1" Margin="10,10,10,10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="1*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
    
                <Button x:Name="BtnPrev" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Width="80" Height="40" Content="PREV MONTH" FontSize="10" Background="White"  Click="BtnPrev_Click"/>
                <TextBlock x:Name="txblkMonth" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="3" Text="XXXX/MM" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <Button x:Name="BtnNext" Grid.Column="5" Grid.Row="0" Grid.ColumnSpan="2" Width="80" Height="40" Content="NEXT MONTH" FontSize="10" Background="White" Click="BtnNext_Click"/>
    
                <TextBlock  x:Name = "su"  Grid.Column="0" Grid.Row="1" Text="Sun" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "mo"  Grid.Column="1" Grid.Row="1" Text="Mon"/>
                <TextBlock  x:Name = "tu"  Grid.Column="2" Grid.Row="1" Text="Tue"/>
                <TextBlock  x:Name = "we"  Grid.Column="3" Grid.Row="1" Text="Wed"/>
                <TextBlock  x:Name = "th"  Grid.Column="4" Grid.Row="1" Text="Thu"/>
                <TextBlock  x:Name = "fr"  Grid.Column="5" Grid.Row="1" Text="Fri"/>
                <TextBlock  x:Name = "sa"  Grid.Column="6" Grid.Row="1" Text="Sat" Foreground="DodgerBlue"/>
    
                <!-- DataContextに設定したmodelのDisplayDatesコレクションのインデックスでバインディング-->
                <TextBlock  x:Name = "d0"  Grid.Column="0" Grid.Row="2" Text="{Binding Path=DisplayDates[0].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d1"  Grid.Column="1" Grid.Row="2" Text="{Binding Path=DisplayDates[1].Day}"/>
                <TextBlock  x:Name = "d2"  Grid.Column="2" Grid.Row="2" Text="{Binding Path=DisplayDates[2].Day}"/>
                <TextBlock  x:Name = "d3"  Grid.Column="3" Grid.Row="2" Text="{Binding Path=DisplayDates[3].Day}"/>
                <TextBlock  x:Name = "d4"  Grid.Column="4" Grid.Row="2" Text="{Binding Path=DisplayDates[4].Day}"/>
                <TextBlock  x:Name = "d5"  Grid.Column="5" Grid.Row="2" Text="{Binding Path=DisplayDates[5].Day}"/>
                <TextBlock  x:Name = "d6"  Grid.Column="6" Grid.Row="2" Text="{Binding Path=DisplayDates[6].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d7"  Grid.Column="0" Grid.Row="3" Text="{Binding Path=DisplayDates[7].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d8"  Grid.Column="1" Grid.Row="3" Text="{Binding Path=DisplayDates[8].Day}" />
                <TextBlock  x:Name = "d9"  Grid.Column="2" Grid.Row="3" Text="{Binding Path=DisplayDates[9].Day}" />
                <TextBlock  x:Name = "d10" Grid.Column="3" Grid.Row="3" Text="{Binding Path=DisplayDates[10].Day}" />
                <TextBlock  x:Name = "d11" Grid.Column="4" Grid.Row="3" Text="{Binding Path=DisplayDates[11].Day}" />
                <TextBlock  x:Name = "d12" Grid.Column="5" Grid.Row="3" Text="{Binding Path=DisplayDates[12].Day}" />
                <TextBlock  x:Name = "d13" Grid.Column="6" Grid.Row="3" Text="{Binding Path=DisplayDates[13].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d14" Grid.Column="0" Grid.Row="4" Text="{Binding Path=DisplayDates[14].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d15" Grid.Column="1" Grid.Row="4" Text="{Binding Path=DisplayDates[15].Day}" />
                <TextBlock  x:Name = "d16" Grid.Column="2" Grid.Row="4" Text="{Binding Path=DisplayDates[16].Day}" />
                <TextBlock  x:Name = "d17" Grid.Column="3" Grid.Row="4" Text="{Binding Path=DisplayDates[17].Day}" />
                <TextBlock  x:Name = "d18" Grid.Column="4" Grid.Row="4" Text="{Binding Path=DisplayDates[18].Day}" />
                <TextBlock  x:Name = "d19" Grid.Column="5" Grid.Row="4" Text="{Binding Path=DisplayDates[19].Day}" />
                <TextBlock  x:Name = "d20" Grid.Column="6" Grid.Row="4" Text="{Binding Path=DisplayDates[20].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d21" Grid.Column="0" Grid.Row="5" Text="{Binding Path=DisplayDates[21].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d22" Grid.Column="1" Grid.Row="5" Text="{Binding Path=DisplayDates[22].Day}" />
                <TextBlock  x:Name = "d23" Grid.Column="2" Grid.Row="5" Text="{Binding Path=DisplayDates[23].Day}" />
                <TextBlock  x:Name = "d24" Grid.Column="3" Grid.Row="5" Text="{Binding Path=DisplayDates[24].Day}" />
                <TextBlock  x:Name = "d25" Grid.Column="4" Grid.Row="5" Text="{Binding Path=DisplayDates[25].Day}" />
                <TextBlock  x:Name = "d26" Grid.Column="5" Grid.Row="5" Text="{Binding Path=DisplayDates[26].Day}" />
                <TextBlock  x:Name = "d27" Grid.Column="6" Grid.Row="5" Text="{Binding Path=DisplayDates[27].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d28" Grid.Column="0" Grid.Row="6" Text="{Binding Path=DisplayDates[28].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d29" Grid.Column="1" Grid.Row="6" Text="{Binding Path=DisplayDates[29].Day}" />
                <TextBlock  x:Name = "d30" Grid.Column="2" Grid.Row="6" Text="{Binding Path=DisplayDates[30].Day}" />
                <TextBlock  x:Name = "d31" Grid.Column="3" Grid.Row="6" Text="{Binding Path=DisplayDates[31].Day}" />
                <TextBlock  x:Name = "d32" Grid.Column="4" Grid.Row="6" Text="{Binding Path=DisplayDates[32].Day}" />
                <TextBlock  x:Name = "d33" Grid.Column="5" Grid.Row="6" Text="{Binding Path=DisplayDates[33].Day}" />
                <TextBlock  x:Name = "d34" Grid.Column="6" Grid.Row="6" Text="{Binding Path=DisplayDates[34].Day}" Foreground="DodgerBlue"/>
                <TextBlock  x:Name = "d35" Grid.Column="0" Grid.Row="7" Text="{Binding Path=DisplayDates[35].Day}" Foreground="OrangeRed"/>
                <TextBlock  x:Name = "d36" Grid.Column="1" Grid.Row="7" Text="{Binding Path=DisplayDates[36].Day}" />
            </Grid>
    
    
            <!-- よりWPFらしいバインディング -->
            <DockPanel>
                <ItemsControl DockPanel.Dock="Top" ItemsSource="{Binding DayOfWeeks}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid Columns="7" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
    
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="t" Text="{Binding Path=.}" 
                                       FontSize="20" Margin="2" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding Path=.}" Value="Sunday">
                                    <Setter TargetName="t" Property="Foreground" Value="OrangeRed"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Path=.}" Value="Saturday">
                                    <Setter TargetName="t" Property="Foreground" Value="DodgerBlue"/>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
    
                <ListBox ItemsSource="{Binding Path=DisplayDates}"
                         BorderThickness="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
                         SelectedItem="{ Binding CurrentDay}">
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid Columns="7" />
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                    
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="t" Text="{Binding Path=Day}" 
                                       FontSize="20" Margin="2" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding Path=DayOfWeek}" Value="Sunday">
                                    <Setter TargetName="t" Property="Foreground" Value="OrangeRed"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Path=DayOfWeek}" Value="Saturday">
                                    <Setter TargetName="t" Property="Foreground" Value="DodgerBlue"/>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DockPanel>
        </UniformGrid>
    </Window>
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    
    namespace WPFCalendarAlpha
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = model;
            }
    
            private Model model = new Model();
    
            private void Window_Loaded(object sender, RoutedEventArgs e) // Window_Loaded Event Property
            {
            }
    
            private void BtnPrev_Click(object sender, RoutedEventArgs e)
            {
                //表示月から1ヶ月引く substract a month from indicated month on the txblkMonth
                model.CreateCalendar(model.FirstDay.AddMonths(-1));
            }
    
            private void BtnNext_Click(object sender, RoutedEventArgs e)
            {
                //表示月に1ヶ月足す add a month to indicated month on the txblkMonth
                model.CreateCalendar(model.FirstDay.AddMonths(+1));
            }
        }
    
        class Model : System.ComponentModel.INotifyPropertyChanged
        {
            public Model()
            {
                CreateCalendar(this.CurrentDay);
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string name)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
    
            public DayOfWeek[] DayOfWeeks => (DayOfWeek[])Enum.GetValues(typeof(DayOfWeek));
    
            public ObservableCollection<DateTime?> DisplayDates { get; }
                = new ObservableCollection<DateTime?>(new DateTime?[37]);//大きさを37で初期化しているだけです
    
            public DateTime FirstDay
            {
                get
                {
                    return _FirstDay;
                }
                set
                {
                    _FirstDay = value;
                    OnPropertyChanged(nameof(FirstDay));
                }
            }
            private DateTime _FirstDay;
    
            public DateTime CurrentDay
            {
                get
                {
                    return _CurrentDay;
                }
                set
                {
                    _CurrentDay = value;
                    OnPropertyChanged(nameof(CurrentDay));
                }
            }
            private DateTime _CurrentDay = DateTime.Today;
    
            public void CreateCalendar(DateTime date)
            {
                this.FirstDay = new DateTime(date.Year, date.Month, 1);
                int diff = -(int)FirstDay.DayOfWeek;
    
                DateTime d = FirstDay.AddDays(diff);
                for (int i = 0; i < 37; i++)
                {
                    DisplayDates[i] = d;
                    d = d.AddDays(1);
                }
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2020年7月30日 0:08 貼り付け失敗
    • 回答としてマーク SuperBeginner 2020年7月30日 11:27
    2020年7月29日 22:54
  • gekkaさん、ありがとうございます。試してみところ、日にちが月をまたいで連続したタイプのカレンダーでしたが、自分が書いたコードの約半分でほとんど同じようなことが出来るのか…と驚きと勉強不足と奥深さがよく分かりました。
    作っているカレンダーを画面に3ヶ月分ほど表示させようと考えていたのですが、連続したタイプのカレンダーの方が良いかな…と考えています。xaml中の配列の扱いの回答もありがとうございます。今後は更に多くの配列を扱う必要があり、大きなヒントになると思います。頂いたコードを調べながら1行ずつ丹念に紐解いて行こうと考えております。ありがとうございました。
    2020年7月30日 11:27