将“今日按钮”添加到日历控件

时间:2012-11-14 16:18:30

标签: .net wpf mvvm calendar controltemplate

我的WPF MVVM应用程序中有以下样式。

<Style x:Key="DefaultCalendar" TargetType="Calendar">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Calendar}">
                <StackPanel HorizontalAlignment="Center" Name="PART_Root">
                    <CalendarItem Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" Name="PART_CalendarItem" Style="{TemplateBinding Calendar.CalendarItemStyle}" />
                    <Button Content="Today" Command="Commands:CalendarCommands.SelectToday" CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我创建了Commands类

namespace Viterra.Freight.Client.Resources.Commands
{
    public class CalendarCommands
    {
        public static RoutedCommand SelectToday = new RoutedCommand("Today", typeof(CalendarCommands));
    }
}

当日历打开时显示,但按钮被禁用。我确定我需要用这个路由命令做更多的事情,所以它设置日期,但我不确定是什么或在哪里。

编辑:最终解决方案 请注意,我也一直在修改DatePicker以使用此日历样式。

<Style x:Key="DefaultCalendar" TargetType="Calendar">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Calendar}">
                <StackPanel HorizontalAlignment="Center" Name="PART_Root">
                    <CalendarItem Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" Name="PART_CalendarItem" Style="{TemplateBinding Calendar.CalendarItemStyle}" />
                    <Button Content="Today" Command="Commands:CalendarCommands.SelectToday" CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- style for default datepicker -->
<Style x:Key="DefaultDatePicker" TargetType="DatePicker">
    <Setter Property="Height" Value="23"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="CalendarStyle" Value="{StaticResource DefaultCalendar}" />
    <Setter Property="Validation.ErrorTemplate" Value="{StaticResource DateTimeValidationTemplate}" />
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>

和CalendarCommands.cs

using System;
using System.Windows.Input;
using System.Windows.Controls;

namespace Viterra.Freight.Client.Resources.Commands
{
    public static class CalendarCommands
    {
        private static readonly SelectTodayCommand _selectTodayCommand = new SelectTodayCommand();

        public static ICommand SelectToday
        {
            get { return _selectTodayCommand; }
        }

        private sealed class SelectTodayCommand : ICommand
        {
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }

            public bool CanExecute(object parameter)
            {
                return parameter is Calendar;
            }

            public void Execute(object parameter)
            {
                var calendar = parameter as Calendar;
                if (calendar == null) 
                    return;

                var today = DateTime.Today;
                calendar.SelectedDate = today;
                calendar.DisplayDate = today;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:4)

或者,如果您不想使用代码隐藏和CommandBindings,则可以使用简单的ICommand实现:

public static class CalendarCommands
{
   private static readonly SelectTodayCommand _selectToday = new SelectTodayCommand();

   public static ICommand SelectToday
   {
      get { return _selectToday; }
   }

   private sealed class SelectTodayCommand : ICommand
   {
      public event EventHandler CanExecuteChanged
      {
         add { CommandManager.RequerySuggested += value; }
         remove { CommandManager.RequerySuggested -= value; }
      }

      public bool CanExecute(object parameter)
      {
         return parameter is Calendar;
      }

      public void Execute(object parameter)
      {
         var calendar = parameter as Calendar;
         if (calendar != null)
         {
            DateTime today = DateTime.Today;
            calendar.SelectedDate = today;
            calendar.DisplayDate = today;
         }
      }
   }
}

答案 1 :(得分:2)

您忘了设置CommandBindings:)

这是一个小工作示例:

<强> MainWindow.xaml

<Window x:Class="WpfApplication13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Commands="clr-namespace:WpfApplication13"
        Title="MainWindow" Height="350" Width="525">

    <Window.CommandBindings>
        <CommandBinding Command="Commands:CalendarCommands.SelectToday"
                        Executed="SelectTodayExecuted"
                        CanExecute="SelectTodayCanExecute"/>
    </Window.CommandBindings>

    <Window.Resources>
        <Style x:Key="DefaultCalendar" TargetType="Calendar">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Calendar}">
                        <StackPanel HorizontalAlignment="Center" Name="PART_Root">
                            <CalendarItem Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" Name="PART_CalendarItem" Style="{TemplateBinding Calendar.CalendarItemStyle}" />
                            <Button Content="Today" Command="Commands:CalendarCommands.SelectToday" CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <Calendar Style="{StaticResource DefaultCalendar}" />
    </Grid>
</Window>

<强> MainWindow.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace WpfApplication13
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void SelectTodayExecuted(object target, ExecutedRoutedEventArgs e)
        {
            // Implement logic here
        }

        private void SelectTodayCanExecute(object target, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
    }

    public class CalendarCommands
    {
        public static RoutedCommand SelectToday = new RoutedCommand("Today", typeof(CalendarCommands));
    }
}