#c# #wpf #calendar
#c# #wpf #Календарь
Вопрос:
Итак, я удалил стандартный элемент управления WPF Calendar
в MainWindow.xaml в совершенно новом приложении WPF в VS2010. Если я нажимаю на день в календаре, а затем пытаюсь нажать кнопку закрытия приложения, мне приходится дважды нажать на кнопку закрытия, прежде чем она примет щелчок. Это действует так, как будто Calendar
не отпустил мышь для взаимодействия с остальной частью приложения.
Я изменил Focusable
значение на false, без изменений в силе, и я пытался переопределить PreviewOnMouseUp
и вызвать ReleaseMouseCapture()
безрезультатно. Я проделал то же самое с MouseLeave
и MouseLeftButtonUp
с тем же результатом. Учитывая, что ни одна из этих вещей не работает, я подозреваю, что я поднимаю неправильное дерево. Google не обнаружил ничего примечательного, хотя, возможно, мой GoogleFu сегодня не на высоте.
Есть идеи?
Ответ №1:
Вы можете изменить это поведение, подписавшись на событие PreviewMouseUp календаря с обработчиком, подобным этому:
private void Calendar_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (Mouse.Captured is CalendarItem)
{
Mouse.Capture(null);
}
}
Комментарии:
1. Это действительно должно быть отмечено как ответ. Принятый ответ объясняет вам, почему это происходит, этот говорит вам, как этого не допустить.
Ответ №2:
Управление календарем размещается во всплывающем окне и захватывает мышь. Когда вы щелкаете в другом месте в первый раз, захват отправляет щелчок во всплывающее окно, которое, понимая, что вы щелкнули вне себя, закрывается. Поэтому щелчок не переходит на кнопку.
Вы можете увидеть тот же эффект при использовании окна со списком. Опустите его вниз, затем нажмите на кнопку. Он не будет нажимать на кнопку.
К сожалению, маловероятно, что вы сможете что-либо сделать, чтобы изменить это поведение.
Редактировать: более поздние версии .NET делают возможным решение. Смотрите ответ Эрена.
Комментарии:
1. Я ничего не вижу о всплывающем окне в иерархии классов календаря. Календарь-> Управление-> etc …-> Object
2. @Ritch Melton: Он по-прежнему может использовать произвольные элементы управления в своем
Template
, поле со списком также не наследуется от этих классов, но также использует всплывающее окно внутри.3. Если вы хотите убедиться в этом сами, воспользуйтесь утилитой snoop Питера Блуа, чтобы посмотреть, где щелчки мыши теряются.
4. Ритч Мелтон запустил snoop, и его результат подтверждает мою точку зрения — CalendarDayButton получает первый щелчок. Обычно всплывающее окно добавляется к визуальному дереву вложенного элемента управления, и мышь захватывается вложенным элементом управления. Вот как работают элементы управления календарем, выпадающим списком и средством выбора даты / времени.
5. Это не должно быть помечено как принятый ответ. Приведенный ниже ответ Эрена набрал наибольшее количество голосов и дает решение проблемы, поэтому OP действительно должен принять его в качестве ответа.
Ответ №3:
Это основа кода, который я использую для решения как проблемы с захватом мыши, так и отсутствия событий щелчка из дочерних элементов управления. Вероятно, это можно еще больше упростить, чтобы сделать управление календарем более доступным напрямую, но лично я склонен добавлять его в 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>
Комментарии:
1. Не стесняйтесь редактировать, чтобы сделать более общим — я буквально вырезал наиболее важные фрагменты из моей текущей кодовой базы и не хотел редактировать слишком много на случай, если я ее сломал.
Ответ №4:
Этот код должен помочь
Calendar.PreviewMouseUp = (o, e) =>
{
if (!e.OriginalSource.Equals(Calendar))
{
Mouse.Capture(null);
}
};
Комментарии:
1. Это не только не работает, но также приводит к тому, что щелчок в некоторых частях календаря закрывает родительское всплывающее окно.