Detecting when a day is clicked on the Silverlight

2019-07-14 23:49发布

I am developing something that will require similar functionality to the Silverlight DatePicker - a popup containing a Calendar control will be shown, and after the user clicks a date, or uses the keyboard to select a date and presses enter/space, the popup should close.

I can show the calender just fine, but I am at a loss at figuring out when the user has clicked a day or pressed enter/space. The SelectedDatesChanged event does not give any indication of whether the user clicked the selected date, or was just passing over it with the keyboard.

Reflector shows that the DatePicker control is cheating, using an internal DayButtonMouseUp event on the Calendar control.

Does anyone know a solution to this problem?

2条回答
淡お忘
2楼-- · 2019-07-15 00:04

You can achieve this by setting the ClickMode of the DayButtons to 'Hover'. After this you can lsiten to the MouseLeftButtonDown-event

    <sdk:Calendar Name="calendar1" MouseLeftButtonDown="calendar1_MouseLeftButtonDown">
        <sdk:Calendar.CalendarDayButtonStyle>
            <Style TargetType="Primitives:CalendarDayButton">
                <Setter Property="ClickMode" Value="Hover"/>
            </Style>
        </sdk:Calendar.CalendarDayButtonStyle>
    </sdk:Calendar>
查看更多
迷人小祖宗
3楼-- · 2019-07-15 00:22

Not a very clean solution. Also, it does not properly take into account BlackoutDates because the IsBlackOut property of the button is also internal. I could manually check against that in my click event, but for my purposes I didn't need to support that.

void CalendarControl_Loaded(object sender, RoutedEventArgs e)
{
    var grid = FindVisualChildByName<Grid>(CalendarControl, "MonthView");
    // Loaded may be called several times before both the grid and day buttons are created
    if (grid != null && grid.Children.OfType<System.Windows.Controls.Primitives.CalendarDayButton>().Any()) 
    {
        // Add our own click event directly to the button
        foreach (var button in grid.Children.OfType<System.Windows.Controls.Primitives.CalendarDayButton>().Cast<System.Windows.Controls.Primitives.CalendarDayButton>())
        {
            button.Click += new RoutedEventHandler(button_Click);
        }
        // We only want to add the event once
        CalendarControl.Loaded -= new RoutedEventHandler(CalendarControl_Loaded);
    }
}

void button_Click(object sender, RoutedEventArgs e)
{
    var button = (System.Windows.Controls.Primitives.CalendarDayButton)sender;
    var date = button.DataContext as DateTime?;
    // The user clicked a date. Close the calendar and do something with it
}

FindVisualChildByName is copied from http://pwnedcode.wordpress.com/2009/04/01/find-a-control-in-a-wpfsilverlight-visual-tree-by-name/

查看更多
登录 后发表回答