Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Calendar Control holding on to the Mouse

Tags:

c#

wpf

calendar

So I dropped the standard WPF Calendar control on the MainWindow.xaml in a brand new WPF App in VS2010. If I click on a day in the calendar and then try to click the Close button for the app, I have to click twice on the close button before it accepts the click. It's acting as if the Calendar hasn't released the Mouse to interact with the rest of the application.

I've changed Focusable to false, with no change in effect, and I've tried overriding the PreviewOnMouseUp and calling ReleaseMouseCapture() to no avail. I've done the same thing with MouseLeave and MouseLeftButtonUp with the same result. Given that none of those things are working I suspect I'm barking up the wrong tree. Google has turned up nothing of note, though perhaps my GoogleFu is not up to snuff today.

Any ideas?

like image 815
Scott Avatar asked May 16 '11 23:05

Scott


3 Answers

You can change this behavior by subscribing to the calendar's PreviewMouseUp event with a handler like this:

private void Calendar_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    if (Mouse.Captured is CalendarItem)
    {
        Mouse.Capture(null);
    }
}
like image 57
Eren Ersönmez Avatar answered Nov 07 '22 02:11

Eren Ersönmez


The calendar control is hosted in a popup, and captures the mouse. When you click somewhere else the first time, the capture sends the click to the popup, which, realizing that you've clicked outside of itself, closes. The click therefore does not go to the button.

You can see the same effect when using a ComboBox. Drop it down, then click on a button. It won't click the button.

Unfortunately, it's unlikely you can do anything to alter this behavior.

Edit: More recent versions of .NET make a solution possible. See Eren's answer.

like image 38
Ed Bayiates Avatar answered Nov 07 '22 01:11

Ed Bayiates


This is the basis of the code I use to work around both the mouse capture issue and the lack of Click events from child controls. It can probably be simplified further to make the calendar control more directly accessible, but I personally tend to add it into the UserControl.

class FixedCalendar : UserControl
{
    public FixedCalendar()
    {
        InitializeComponent();
    }

    protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseUp(e);
        if (Mouse.Captured is System.Windows.Controls.Primitives.CalendarItem)
        {
            Mouse.Capture(null);

            var element = e.OriginalSource as FrameworkElement;
            if (element != null)
                element.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
        }
    }
}

<UserControl x:Class="FixedCalendar"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Calendar x:Name="Calendar" />
</UserControl>
like image 1
Zooba Avatar answered Nov 07 '22 02:11

Zooba