From a2a82aedf84b88274ac70815aa1ce66a14e0bf55 Mon Sep 17 00:00:00 2001 From: Shankar Date: Fri, 6 Nov 2020 15:07:25 +0530 Subject: [PATCH 1/8] Added localization string resources of TeachingTip --- ModernWpf/Resources/Strings.Designer.cs | 45 ++++++++++++++++++++++++ ModernWpf/Resources/Strings.cs.resx | 20 +++++++++++ ModernWpf/Resources/Strings.de.resx | 20 +++++++++++ ModernWpf/Resources/Strings.es.resx | 20 +++++++++++ ModernWpf/Resources/Strings.fa.resx | 20 +++++++++++ ModernWpf/Resources/Strings.fr.resx | 20 +++++++++++ ModernWpf/Resources/Strings.it.resx | 20 +++++++++++ ModernWpf/Resources/Strings.ja.resx | 20 +++++++++++ ModernWpf/Resources/Strings.ko.resx | 20 +++++++++++ ModernWpf/Resources/Strings.pl.resx | 20 +++++++++++ ModernWpf/Resources/Strings.pt-BR.resx | 20 +++++++++++ ModernWpf/Resources/Strings.resx | 20 +++++++++++ ModernWpf/Resources/Strings.ru.resx | 20 +++++++++++ ModernWpf/Resources/Strings.tr.resx | 20 +++++++++++ ModernWpf/Resources/Strings.zh-Hans.resx | 20 +++++++++++ ModernWpf/Resources/Strings.zh-Hant.resx | 20 +++++++++++ 16 files changed, 345 insertions(+) diff --git a/ModernWpf/Resources/Strings.Designer.cs b/ModernWpf/Resources/Strings.Designer.cs index c0c13c54..26d834db 100644 --- a/ModernWpf/Resources/Strings.Designer.cs +++ b/ModernWpf/Resources/Strings.Designer.cs @@ -438,6 +438,51 @@ internal class Strings { } } + /// + /// Looks up a localized string similar to Close. + /// + internal static string TeachingTipAlternateCloseButtonName { + get { + return ResourceManager.GetString("TeachingTipAlternateCloseButtonName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close. + /// + internal static string TeachingTipAlternateCloseButtonTooltip { + get { + return ResourceManager.GetString("TeachingTipAlternateCloseButtonTooltip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tip. + /// + internal static string TeachingTipCustomLandmarkName { + get { + return ResourceManager.GetString("TeachingTipCustomLandmarkName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Press F6 to go to new notification from {0}, {1}.. + /// + internal static string TeachingTipNotification { + get { + return ResourceManager.GetString("TeachingTipNotification", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Press F6 to go to new notification, {0}.. + /// + internal static string TeachingTipNotificationWithoutAppName { + get { + return ResourceManager.GetString("TeachingTipNotificationWithoutAppName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Copy. /// diff --git a/ModernWpf/Resources/Strings.cs.resx b/ModernWpf/Resources/Strings.cs.resx index 6dbe4631..51f2744a 100644 --- a/ModernWpf/Resources/Strings.cs.resx +++ b/ModernWpf/Resources/Strings.cs.resx @@ -268,4 +268,24 @@ Nastavení Automation name for the settings button + + Zavřít + This is the automation name of the alternate close button. + + + Zavřít + This is the string used for the alternate close button's tooltip + + + Tip + This is the custom landmark used to denote a tip to narrator. + + + Stisknutím klávesy F6 přejdete na nové oznámení z aplikace {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Stisknutím klávesy F6 přejdete na nové oznámení, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.de.resx b/ModernWpf/Resources/Strings.de.resx index ce267646..56dd89eb 100644 --- a/ModernWpf/Resources/Strings.de.resx +++ b/ModernWpf/Resources/Strings.de.resx @@ -268,4 +268,24 @@ Einstellungen Automation name for the settings button + + Schließen + This is the automation name of the alternate close button. + + + Schließen + This is the string used for the alternate close button's tooltip + + + Tipp + This is the custom landmark used to denote a tip to narrator. + + + Drücken Sie F6, um auf die neue Benachrichtigung zu {0}, {1} zuzugreifen. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Drücken Sie F6, um auf die neue Benachrichtigung zu {0} zuzugreifen. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.es.resx b/ModernWpf/Resources/Strings.es.resx index 20e0b569..2c1af593 100644 --- a/ModernWpf/Resources/Strings.es.resx +++ b/ModernWpf/Resources/Strings.es.resx @@ -268,4 +268,24 @@ Configuración Automation name for the settings button + + Cerrar + This is the automation name of the alternate close button. + + + Cerrar + This is the string used for the alternate close button's tooltip + + + Sugerencia + This is the custom landmark used to denote a tip to narrator. + + + Presiona F6 para ir a la nueva notificación de {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Presiona F6 para ir a la nueva notificación, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.fa.resx b/ModernWpf/Resources/Strings.fa.resx index 421c8598..40dcf744 100644 --- a/ModernWpf/Resources/Strings.fa.resx +++ b/ModernWpf/Resources/Strings.fa.resx @@ -313,4 +313,24 @@ تنظیمات Automation name for the settings button + + بستن + This is the automation name of the alternate close button. + + + بستن + This is the string used for the alternate close button's tooltip + + + ترفند + This is the custom landmark used to denote a tip to narrator. + + + برای رفتن به اعلان جدید از {0}، {1}، F6 را فشار دهید. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + برای رفتن به اعلان جدید از {0}، F6 را فشار دهید. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.fr.resx b/ModernWpf/Resources/Strings.fr.resx index a496cd1e..dfc090c2 100644 --- a/ModernWpf/Resources/Strings.fr.resx +++ b/ModernWpf/Resources/Strings.fr.resx @@ -268,4 +268,24 @@ Paramètres Automation name for the settings button + + Fermer + This is the automation name of the alternate close button. + + + Fermer + This is the string used for the alternate close button's tooltip + + + Astuce + This is the custom landmark used to denote a tip to narrator. + + + Appuyez sur F6 pour accéder à la nouvelle notification de {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Appuyez sur F6 pour accéder à la nouvelle notification, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.it.resx b/ModernWpf/Resources/Strings.it.resx index 8ec3d029..4795b531 100644 --- a/ModernWpf/Resources/Strings.it.resx +++ b/ModernWpf/Resources/Strings.it.resx @@ -268,4 +268,24 @@ Impostazioni Automation name for the settings button + + Chiudi + This is the automation name of the alternate close button. + + + Chiudi + This is the string used for the alternate close button's tooltip + + + Suggerimento + This is the custom landmark used to denote a tip to narrator. + + + Premi F6 per passare alla nuova notifica da {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Premi F6 per passare alla nuova notifica, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.ja.resx b/ModernWpf/Resources/Strings.ja.resx index 68d0de58..cf9f0669 100644 --- a/ModernWpf/Resources/Strings.ja.resx +++ b/ModernWpf/Resources/Strings.ja.resx @@ -268,4 +268,24 @@ 設定 Automation name for the settings button + + 閉じる + This is the automation name of the alternate close button. + + + 閉じる + This is the string used for the alternate close button's tooltip + + + ヒント + This is the custom landmark used to denote a tip to narrator. + + + {0} からの新しい通知 ({1}) にアクセスするには、F6 キーを押してください。 + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + 新しい通知 {0} にアクセスするには、F6 キーを押してください。 + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.ko.resx b/ModernWpf/Resources/Strings.ko.resx index 17b7bf2f..ef9c201c 100644 --- a/ModernWpf/Resources/Strings.ko.resx +++ b/ModernWpf/Resources/Strings.ko.resx @@ -268,4 +268,24 @@ 설정 Automation name for the settings button + + 닫기 + This is the automation name of the alternate close button. + + + 닫기 + This is the string used for the alternate close button's tooltip + + + + This is the custom landmark used to denote a tip to narrator. + + + F6 키를 눌러 {0}, {1}의 새 알림으로 이동하세요. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + F6 키를 눌러 새 알림, {0}(으)로 이동하세요. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.pl.resx b/ModernWpf/Resources/Strings.pl.resx index 046df708..e4fb8b27 100644 --- a/ModernWpf/Resources/Strings.pl.resx +++ b/ModernWpf/Resources/Strings.pl.resx @@ -268,4 +268,24 @@ Ustawienia Automation name for the settings button + + Zamknij + This is the automation name of the alternate close button. + + + Zamknij + This is the string used for the alternate close button's tooltip + + + Wskazówka + This is the custom landmark used to denote a tip to narrator. + + + Naciśnij klawisz F6, aby przejść do nowego powiadomienia z aplikacji {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Naciśnij klawisz F6, aby przejść do nowego powiadomienia {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.pt-BR.resx b/ModernWpf/Resources/Strings.pt-BR.resx index 109b7eb4..4e22c074 100644 --- a/ModernWpf/Resources/Strings.pt-BR.resx +++ b/ModernWpf/Resources/Strings.pt-BR.resx @@ -268,4 +268,24 @@ Configurações Automation name for the settings button + + Fechar + This is the automation name of the alternate close button. + + + Fechar + This is the string used for the alternate close button's tooltip + + + Dica + This is the custom landmark used to denote a tip to narrator. + + + Pressione F6 para ir para a nova notificação de {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Pressione F6 para ir para a nova notificação, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.resx b/ModernWpf/Resources/Strings.resx index 470f248a..12657c6f 100644 --- a/ModernWpf/Resources/Strings.resx +++ b/ModernWpf/Resources/Strings.resx @@ -317,4 +317,24 @@ More ToolTip caption for the nav view more button when panel is on top + + Close + This is the automation name of the alternate close button. + + + Close + This is the string used for the alternate close button's tooltip + + + Tip + This is the custom landmark used to denote a tip to narrator. + + + Press F6 to go to new notification from {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Press F6 to go to new notification, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.ru.resx b/ModernWpf/Resources/Strings.ru.resx index 5c3f268f..125059ed 100644 --- a/ModernWpf/Resources/Strings.ru.resx +++ b/ModernWpf/Resources/Strings.ru.resx @@ -268,4 +268,24 @@ Параметры Automation name for the settings button + + Закрыть + This is the automation name of the alternate close button. + + + Закрыть + This is the string used for the alternate close button's tooltip + + + Совет + This is the custom landmark used to denote a tip to narrator. + + + Нажмите клавишу F6, чтобы перейти к новому уведомлению от {0}, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Нажмите клавишу F6, чтобы перейти к новому уведомлению, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.tr.resx b/ModernWpf/Resources/Strings.tr.resx index 1e56c30d..f8a25694 100644 --- a/ModernWpf/Resources/Strings.tr.resx +++ b/ModernWpf/Resources/Strings.tr.resx @@ -268,4 +268,24 @@ Ayarlar Automation name for the settings button + + Kapat + This is the automation name of the alternate close button. + + + Kapat + This is the string used for the alternate close button's tooltip + + + İpucu + This is the custom landmark used to denote a tip to narrator. + + + {0} tarafından gelen yeni bildirime gitmek için F6 tuşuna basın, {1}. + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + Yeni bildirime gitmek için F6 tuşuna basın, {0}. + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.zh-Hans.resx b/ModernWpf/Resources/Strings.zh-Hans.resx index 502d5c7c..6cb13443 100644 --- a/ModernWpf/Resources/Strings.zh-Hans.resx +++ b/ModernWpf/Resources/Strings.zh-Hans.resx @@ -268,4 +268,24 @@ 设置 Automation name for the settings button + + 关闭 + This is the automation name of the alternate close button. + + + 关闭 + This is the string used for the alternate close button's tooltip + + + 提示 + This is the custom landmark used to denote a tip to narrator. + + + 按 F6 转到来自 {0}、{1} 新的通知。 + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + 按 F6 转到新的通知 {0}。 + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file diff --git a/ModernWpf/Resources/Strings.zh-Hant.resx b/ModernWpf/Resources/Strings.zh-Hant.resx index d082322d..7d3e32ff 100644 --- a/ModernWpf/Resources/Strings.zh-Hant.resx +++ b/ModernWpf/Resources/Strings.zh-Hant.resx @@ -268,4 +268,24 @@ 設定 Automation name for the settings button + + 關閉 + This is the automation name of the alternate close button. + + + 關閉 + This is the string used for the alternate close button's tooltip + + + 提示 + This is the custom landmark used to denote a tip to narrator. + + + 按一下 F6,前往來自 {0},{1} 的新通知。 + This is the formarted string read by narrator when a new tip is opened. It is "Press F6 to go to new notification from 'AppName', 'TipTitle'. + + + 按一下 F6 前往新通知,{0}。 + This is the formatted string read by narrator when a new tip is opened and the app name is not available. it is "Press F6 to go to new notification, 'TipTitle'. + \ No newline at end of file From 690c807ee2e0015bde517c085be25a60a70ba81d Mon Sep 17 00:00:00 2001 From: Shankar Date: Fri, 6 Nov 2020 15:09:03 +0530 Subject: [PATCH 2/8] Initial porting --- ModernWpf.Controls/TeachingTip/Enums.cs | 45 ++++++ ModernWpf.Controls/TeachingTip/TeachingTip.cs | 8 ++ .../TeachingTip/TeachingTipAutomationPeer.cs | 131 ++++++++++++++++++ .../TeachingTip/TeachingTipClosedEventArgs.cs | 14 ++ .../TeachingTipClosingEventArgs.cs | 50 +++++++ .../TeachingTipTemplateSettings.cs | 59 ++++++++ ModernWpf/Common/Deferral.cs | 38 +++++ 7 files changed, 345 insertions(+) create mode 100644 ModernWpf.Controls/TeachingTip/Enums.cs create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTip.cs create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTipClosedEventArgs.cs create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTipClosingEventArgs.cs create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTipTemplateSettings.cs create mode 100644 ModernWpf/Common/Deferral.cs diff --git a/ModernWpf.Controls/TeachingTip/Enums.cs b/ModernWpf.Controls/TeachingTip/Enums.cs new file mode 100644 index 00000000..7253852f --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/Enums.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + + +namespace ModernWpf.Controls +{ + public enum TeachingTipTailVisibility + { + Auto, + Visible, + Collapsed, + }; + + public enum TeachingTipCloseReason + { + CloseButton, + LightDismiss, + Programmatic, + }; + + public enum TeachingTipPlacementMode + { + Auto, + Top, + Bottom, + Left, + Right, + TopRight, + TopLeft, + BottomRight, + BottomLeft, + LeftTop, + LeftBottom, + RightTop, + RightBottom, + Center + }; + + public enum TeachingTipHeroContentPlacementMode + { + Auto, + Top, + Bottom, + }; +} diff --git a/ModernWpf.Controls/TeachingTip/TeachingTip.cs b/ModernWpf.Controls/TeachingTip/TeachingTip.cs new file mode 100644 index 00000000..6385f7c1 --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTip.cs @@ -0,0 +1,8 @@ +using System.Windows.Controls; + +namespace ModernWpf.Controls +{ + public class TeachingTip : ContentControl + { + } +} diff --git a/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs b/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs new file mode 100644 index 00000000..c830dfdc --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs @@ -0,0 +1,131 @@ +using System.Windows.Automation; +using System.Windows.Automation.Peers; +using ModernWpf.Controls; + +namespace ModernWpf.Automation.Peers +{ + public class TeachingTipAutomationPeer : FrameworkElementAutomationPeer + { + public TeachingTipAutomationPeer(TeachingTip owner) : base(owner) + { + } + + protected override AutomationControlType GetAutomationControlTypeCore() + { + if (GetTeachingTip() != null/*.IsLightDismissEnabled*/) + { + return AutomationControlType.Window; + } + else + { + return AutomationControlType.Pane; + } + } + + protected override string GetClassNameCore() + { + return nameof(TeachingTip); + } + + private WindowInteractionState InteractionState() + { + //var teachingTip = GetTeachingTip(); + //if (teachingTip.m_isIdle && teachingTip.IsOpen) + //{ + // return WindowInteractionState.ReadyForUserInteraction; + //} + //else if (teachingTip.m_isIdle && !teachingTip.IsOpen) + //{ + // return WindowInteractionState.BlockedByModalWindow; + //} + //else if (!teachingTip.m_isIdle && !teachingTip.IsOpen) + //{ + // return WindowInteractionState.Closing; + //} + //else + //{ + // return WindowInteractionState.Running; + //} + + return WindowInteractionState.Running; + } + + private bool IsModal() + { + return GetTeachingTip() != null/*.IsLightDismissEnabled*/; + } + + private bool IsTopMost() + { + return GetTeachingTip() != null/*.IsOpen*/; + } + + private bool Maximizable() + { + return false; + } + + private bool Minimizable() + { + return false; + } + + private WindowVisualState VisualState() + { + return WindowVisualState.Normal; + } + + private void Close() + { + GetTeachingTip()/*.IsOpen = false*/; + } + + private void SetVisualState(WindowVisualState state) + { + + } + + private bool WaitForInputIdle(int milliseconds) + { + return true; + } + + // Didn't implement these as AutomationEvents.WindowOpened & AutomationEvents.WindowClosed are not present in WPF + + //internal void RaiseWindowClosedEvent() + //{ + // We only report as a window when light dismiss is enabled. + // if (GetTeachingTip().IsLightDismissEnabled && + // ListenerExists(AutomationEvents.WindowClosed)) + // { + // RaiseAutomationEvent(AutomationEvents.WindowClosed); + // } + //} + + //internal void RaiseWindowOpenedEvent(string displayString) + //{ + // AutomationPeer automationPeer7 = this; + // if (automationPeer7 != null) + // { + // //automationPeer7.RaiseNotificationEvent( + // // Automation.Peers.AutomationNotificationKind.Other, + // // Peers.AutomationNotificationProcessing.CurrentThenMostRecent, + // // displayString, + // // L"TeachingTipOpenedActivityId"); + // } + + // // We only report as a window when light dismiss is enabled. + // if (GetTeachingTip().IsLightDismissEnabled && + // AutomationPeer.ListenerExists(AutomationEvents.WindowOpened)) + // { + // RaiseAutomationEvent(AutomationEvents.WindowOpened); + // } + //} + + TeachingTip GetTeachingTip() + { + var owner = Owner; + return (TeachingTip)owner; + } + } +} diff --git a/ModernWpf.Controls/TeachingTip/TeachingTipClosedEventArgs.cs b/ModernWpf.Controls/TeachingTip/TeachingTipClosedEventArgs.cs new file mode 100644 index 00000000..3951854d --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTipClosedEventArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace ModernWpf.Controls +{ + public sealed class TeachingTipClosedEventArgs : EventArgs + { + internal TeachingTipClosedEventArgs(TeachingTipCloseReason reason) + { + Reason = reason; + } + + public TeachingTipCloseReason Reason { get; } + } +} diff --git a/ModernWpf.Controls/TeachingTip/TeachingTipClosingEventArgs.cs b/ModernWpf.Controls/TeachingTip/TeachingTipClosingEventArgs.cs new file mode 100644 index 00000000..3d855163 --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTipClosingEventArgs.cs @@ -0,0 +1,50 @@ +using System; +using System.Diagnostics; + +namespace ModernWpf.Controls +{ + public sealed class TeachingTipClosingEventArgs : EventArgs + { + private Deferral m_deferral; + private int m_deferralCount; + + internal TeachingTipClosingEventArgs(TeachingTipCloseReason reason) + { + Reason = reason; + } + + public bool Cancel { get; set; } + + public TeachingTipCloseReason Reason { get; } + + public Deferral GetDeferral() + { + m_deferralCount++; + + return new Deferral(() => + { + DecrementDeferralCount(); + }); + } + + internal void SetDeferral(Deferral deferral) + { + m_deferral = deferral; + } + + internal void DecrementDeferralCount() + { + Debug.Assert(m_deferralCount > 0); + m_deferralCount--; + if (m_deferralCount == 0) + { + m_deferral.Complete(); + } + } + + internal void IncrementDeferralCount() + { + m_deferralCount++; + } + } +} diff --git a/ModernWpf.Controls/TeachingTip/TeachingTipTemplateSettings.cs b/ModernWpf.Controls/TeachingTip/TeachingTipTemplateSettings.cs new file mode 100644 index 00000000..672e2c94 --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTipTemplateSettings.cs @@ -0,0 +1,59 @@ +using System.Windows; + +namespace ModernWpf.Controls +{ + public class TeachingTipTemplateSettings : DependencyObject + { + public TeachingTipTemplateSettings() + { + } + + #region IconElement + + public static readonly DependencyProperty IconElementProperty = + DependencyProperty.Register( + nameof(IconElement), + typeof(IconElement), + typeof(TeachingTipTemplateSettings)); + + public IconElement IconElement + { + get => (IconElement)GetValue(IconElementProperty); + set => SetValue(IconElementProperty, value); + } + + #endregion + + #region TopLeftHighlightMargin + + public static readonly DependencyProperty TopLeftHighlightMarginProperty = + DependencyProperty.Register( + nameof(TopLeftHighlightMargin), + typeof(Thickness), + typeof(TeachingTipTemplateSettings)); + + public Thickness TopLeftHighlightMargin + { + get => (Thickness)GetValue(TopLeftHighlightMarginProperty); + set => SetValue(TopLeftHighlightMarginProperty, value); + } + + #endregion + + #region TopRightHighlightMargin + + public static readonly DependencyProperty TopRightHighlightMarginProperty = + DependencyProperty.Register( + nameof(TopRightHighlightMargin), + typeof(Thickness), + typeof(TeachingTipTemplateSettings)); + + public Thickness TopRightHighlightMargin + { + get => (Thickness)GetValue(TopRightHighlightMarginProperty); + set => SetValue(TopRightHighlightMarginProperty, value); + } + + #endregion + } +} diff --git a/ModernWpf/Common/Deferral.cs b/ModernWpf/Common/Deferral.cs new file mode 100644 index 00000000..d7affdcb --- /dev/null +++ b/ModernWpf/Common/Deferral.cs @@ -0,0 +1,38 @@ +using System; +using System.Runtime.InteropServices; + +namespace ModernWpf +{ + /// + /// Represents a method that handles the completed event of a deferred action. + /// + public delegate void DeferralCompletedHandler(); + + /// + /// Stores a to be invoked upon completion of the deferral + /// and manipulates the state of the deferral. + /// + public class Deferral : IDisposable + { + private readonly DeferralCompletedHandler _handler; + + /// + /// Initializes a new object and specifies a + /// to be called upon completion of the deferral. + /// + /// A to be called upon completion of the deferral. + public Deferral([In] DeferralCompletedHandler handler) + { + _handler = handler; + } + + /// + /// If the has not yet been invoked, this will call it + /// and drop the reference to the delegate. + /// + public void Complete() => _handler?.Invoke(); + + /// + public void Dispose() { } + } +} From ca96f26f7610688884d0c641d0b3d45499ecc0b9 Mon Sep 17 00:00:00 2001 From: Shankar Date: Fri, 6 Nov 2020 23:24:05 +0530 Subject: [PATCH 3/8] Ported theme resources of TeachingTip --- .../TeachingTip/TeachingTip.xaml | 48 +++++++++++++++ .../TeachingTip/TeachingTipAutomationPeer.cs | 58 +++++++++---------- ModernWpf/ThemeResources/Dark.xaml | 10 ++++ ModernWpf/ThemeResources/HighContrast.xaml | 10 ++++ ModernWpf/ThemeResources/Light.xaml | 10 ++++ 5 files changed, 107 insertions(+), 29 deletions(-) create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTip.xaml diff --git a/ModernWpf.Controls/TeachingTip/TeachingTip.xaml b/ModernWpf.Controls/TeachingTip/TeachingTip.xaml new file mode 100644 index 00000000..eb97a01c --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTip.xaml @@ -0,0 +1,48 @@ + + + + 40 + 520 + 320 + 336 + + 6,12,0,0 + 0,12,6,0 + + 0,12,0,0 + 0,0,0,0 + + 0,0,28,0 + 0,0,0,0 + + 0,0,12,0 + 0,0,0,0 + + 1,1,1,0 + 1,0,1,1 + 1,1,0,1 + 0,1,1,1 + 1,1,1,1 + + 0,-2,0,0 + 0,0,0,-2 + -2,0,0,0 + 0,0,-2,0 + + 8 + 10 + + 40 + 12 + + 12 + + 1 + 1 + 0,1,0,0 + + \ No newline at end of file diff --git a/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs b/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs index c830dfdc..d881cd2d 100644 --- a/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs +++ b/ModernWpf.Controls/TeachingTip/TeachingTipAutomationPeer.cs @@ -92,35 +92,35 @@ private bool WaitForInputIdle(int milliseconds) // Didn't implement these as AutomationEvents.WindowOpened & AutomationEvents.WindowClosed are not present in WPF - //internal void RaiseWindowClosedEvent() - //{ - // We only report as a window when light dismiss is enabled. - // if (GetTeachingTip().IsLightDismissEnabled && - // ListenerExists(AutomationEvents.WindowClosed)) - // { - // RaiseAutomationEvent(AutomationEvents.WindowClosed); - // } - //} - - //internal void RaiseWindowOpenedEvent(string displayString) - //{ - // AutomationPeer automationPeer7 = this; - // if (automationPeer7 != null) - // { - // //automationPeer7.RaiseNotificationEvent( - // // Automation.Peers.AutomationNotificationKind.Other, - // // Peers.AutomationNotificationProcessing.CurrentThenMostRecent, - // // displayString, - // // L"TeachingTipOpenedActivityId"); - // } - - // // We only report as a window when light dismiss is enabled. - // if (GetTeachingTip().IsLightDismissEnabled && - // AutomationPeer.ListenerExists(AutomationEvents.WindowOpened)) - // { - // RaiseAutomationEvent(AutomationEvents.WindowOpened); - // } - //} + internal void RaiseWindowClosedEvent() + { + //We only report as a window when light dismiss is enabled. + //if (GetTeachingTip().IsLightDismissEnabled && + // ListenerExists(AutomationEvents.WindowClosed)) + //{ + // RaiseAutomationEvent(AutomationEvents.WindowClosed); + //} + } + + internal void RaiseWindowOpenedEvent(string displayString) + { + //AutomationPeer automationPeer7 = this; + //if (automationPeer7 != null) + //{ + // //automationPeer7.RaiseNotificationEvent( + // // Automation.Peers.AutomationNotificationKind.Other, + // // Peers.AutomationNotificationProcessing.CurrentThenMostRecent, + // // displayString, + // // L"TeachingTipOpenedActivityId"); + //} + + //// We only report as a window when light dismiss is enabled. + //if (GetTeachingTip().IsLightDismissEnabled && + // AutomationPeer.ListenerExists(AutomationEvents.WindowOpened)) + //{ + // RaiseAutomationEvent(AutomationEvents.WindowOpened); + //} + } TeachingTip GetTeachingTip() { diff --git a/ModernWpf/ThemeResources/Dark.xaml b/ModernWpf/ThemeResources/Dark.xaml index 09bad059..2d5abbdb 100644 --- a/ModernWpf/ThemeResources/Dark.xaml +++ b/ModernWpf/ThemeResources/Dark.xaml @@ -1186,6 +1186,16 @@ + + + + + + + + + 0 + diff --git a/ModernWpf/ThemeResources/HighContrast.xaml b/ModernWpf/ThemeResources/HighContrast.xaml index 451bd272..88f90479 100644 --- a/ModernWpf/ThemeResources/HighContrast.xaml +++ b/ModernWpf/ThemeResources/HighContrast.xaml @@ -1188,6 +1188,16 @@ + + + + + + + + + 2 + diff --git a/ModernWpf/ThemeResources/Light.xaml b/ModernWpf/ThemeResources/Light.xaml index fa84d95e..2cce696b 100644 --- a/ModernWpf/ThemeResources/Light.xaml +++ b/ModernWpf/ThemeResources/Light.xaml @@ -1185,6 +1185,16 @@ + + + + + + + + + 0 + From eba268eaef733efaaa90b77505f2f04db7c3f3c4 Mon Sep 17 00:00:00 2001 From: Shankar Date: Thu, 12 Nov 2020 15:42:29 +0530 Subject: [PATCH 4/8] Added properties, DPs and events --- .../TeachingTip/TeachingTip.Properties.cs | 513 ++++ ModernWpf.Controls/TeachingTip/TeachingTip.cs | 2445 ++++++++++++++++- .../TeachingTip/TeachingTipAutomationPeer.cs | 44 +- 3 files changed, 2977 insertions(+), 25 deletions(-) create mode 100644 ModernWpf.Controls/TeachingTip/TeachingTip.Properties.cs diff --git a/ModernWpf.Controls/TeachingTip/TeachingTip.Properties.cs b/ModernWpf.Controls/TeachingTip/TeachingTip.Properties.cs new file mode 100644 index 00000000..7a326539 --- /dev/null +++ b/ModernWpf.Controls/TeachingTip/TeachingTip.Properties.cs @@ -0,0 +1,513 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using System.Windows; +using System.Windows.Input; +using ModernWpf.Controls.Primitives; + +namespace ModernWpf.Controls +{ + public partial class TeachingTip + { + #region ActionButtonCommand + + public static readonly DependencyProperty ActionButtonCommandProperty = + DependencyProperty.Register( + nameof(ActionButtonCommand), + typeof(ICommand), + typeof(TeachingTip), + new PropertyMetadata(OnActionButtonCommandPropertyChanged)); + + public ICommand ActionButtonCommand + { + get => (ICommand)GetValue(ActionButtonCommandProperty); + set => SetValue(ActionButtonCommandProperty, value); + } + + private static void OnActionButtonCommandPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region ActionButtonCommandParameter + + public static readonly DependencyProperty ActionButtonCommandParameterProperty = + DependencyProperty.Register( + nameof(ActionButtonCommandParameter), + typeof(object), + typeof(TeachingTip), + new PropertyMetadata(OnActionButtonCommandParameterPropertyChanged)); + + public object ActionButtonCommandParameter + { + get => (object)GetValue(ActionButtonCommandParameterProperty); + set => SetValue(ActionButtonCommandParameterProperty, value); + } + + private static void OnActionButtonCommandParameterPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region ActionButtonContent + + public static readonly DependencyProperty ActionButtonContentProperty = + DependencyProperty.Register( + nameof(ActionButtonContent), + typeof(object), + typeof(TeachingTip), + new PropertyMetadata(OnActionButtonContentPropertyChanged)); + + public object ActionButtonContent + { + get => (object)GetValue(ActionButtonContentProperty); + set => SetValue(ActionButtonContentProperty, value); + } + + private static void OnActionButtonContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region ActionButtonStyle + + public static readonly DependencyProperty ActionButtonStyleProperty = + DependencyProperty.Register( + nameof(ActionButtonStyle), + typeof(Style), + typeof(TeachingTip), + new PropertyMetadata(OnActionButtonStylePropertyChanged)); + + public Style ActionButtonStyle + { + get => (Style)GetValue(ActionButtonStyleProperty); + set => SetValue(ActionButtonStyleProperty, value); + } + + private static void OnActionButtonStylePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region CloseButtonCommand + + public static readonly DependencyProperty CloseButtonCommandProperty = + DependencyProperty.Register( + nameof(CloseButtonCommand), + typeof(ICommand), + typeof(TeachingTip), + new PropertyMetadata(OnCloseButtonCommandPropertyChanged)); + + public ICommand CloseButtonCommand + { + get => (ICommand)GetValue(CloseButtonCommandProperty); + set => SetValue(CloseButtonCommandProperty, value); + } + + private static void OnCloseButtonCommandPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region CloseButtonCommandParameter + + public static readonly DependencyProperty CloseButtonCommandParameterProperty = + DependencyProperty.Register( + nameof(CloseButtonCommandParameter), + typeof(object), + typeof(TeachingTip), + new PropertyMetadata(OnCloseButtonCommandParameterPropertyChanged)); + + public object CloseButtonCommandParameter + { + get => (object)GetValue(CloseButtonCommandParameterProperty); + set => SetValue(CloseButtonCommandParameterProperty, value); + } + + private static void OnCloseButtonCommandParameterPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region CloseButtonContent + + public static readonly DependencyProperty CloseButtonContentProperty = + DependencyProperty.Register( + nameof(CloseButtonContent), + typeof(object), + typeof(TeachingTip), + new PropertyMetadata(OnCloseButtonContentPropertyChanged)); + + public object CloseButtonContent + { + get => (object)GetValue(CloseButtonContentProperty); + set => SetValue(CloseButtonContentProperty, value); + } + + private static void OnCloseButtonContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region CloseButtonStyle + + public static readonly DependencyProperty CloseButtonStyleProperty = + DependencyProperty.Register( + nameof(CloseButtonStyle), + typeof(Style), + typeof(TeachingTip), + new PropertyMetadata(OnCloseButtonStylePropertyChanged)); + + public Style CloseButtonStyle + { + get => (Style)GetValue(CloseButtonStyleProperty); + set => SetValue(CloseButtonStyleProperty, value); + } + + private static void OnCloseButtonStylePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region HeroContent + + public static readonly DependencyProperty HeroContentProperty = + DependencyProperty.Register( + nameof(HeroContent), + typeof(UIElement), + typeof(TeachingTip), + new PropertyMetadata(OnHeroContentPropertyChanged)); + + public UIElement HeroContent + { + get => (UIElement)GetValue(HeroContentProperty); + set => SetValue(HeroContentProperty, value); + } + + private static void OnHeroContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region HeroContentPlacement + + public static readonly DependencyProperty HeroContentPlacementProperty = + DependencyProperty.Register( + nameof(HeroContentPlacement), + typeof(TeachingTipHeroContentPlacementMode), + typeof(TeachingTip), + new PropertyMetadata(TeachingTipHeroContentPlacementMode.Auto, OnHeroContentPlacementPropertyChanged)); + + public TeachingTipHeroContentPlacementMode HeroContentPlacement + { + get => (TeachingTipHeroContentPlacementMode)GetValue(HeroContentPlacementProperty); + set => SetValue(HeroContentPlacementProperty, value); + } + + private static void OnHeroContentPlacementPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region IconSource + + public static readonly DependencyProperty IconSourceProperty = + DependencyProperty.Register( + nameof(IconSource), + typeof(IconSource), + typeof(TeachingTip), + new PropertyMetadata(OnIconSourcePropertyChanged)); + + public IconSource IconSource + { + get => (IconSource)GetValue(IconSourceProperty); + set => SetValue(IconSourceProperty, value); + } + + private static void OnIconSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region IsLightDismissEnabled + + public static readonly DependencyProperty IsLightDismissEnabledProperty = + DependencyProperty.Register( + nameof(IsLightDismissEnabled), + typeof(bool), + typeof(TeachingTip), + new PropertyMetadata(false, OnIsLightDismissEnabledPropertyChanged)); + + public bool IsLightDismissEnabled + { + get => (bool)GetValue(IsLightDismissEnabledProperty); + set => SetValue(IsLightDismissEnabledProperty, value); + } + + private static void OnIsLightDismissEnabledPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region IsOpen + + public static readonly DependencyProperty IsOpenProperty = + DependencyProperty.Register( + nameof(IsOpen), + typeof(bool), + typeof(TeachingTip), + new PropertyMetadata(false, OnIsOpenPropertyChanged)); + + public bool IsOpen + { + get => (bool)GetValue(IsOpenProperty); + set => SetValue(IsOpenProperty, value); + } + + private static void OnIsOpenPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region PlacementMargin + + public static readonly DependencyProperty PlacementMarginProperty = + DependencyProperty.Register( + nameof(PlacementMargin), + typeof(Thickness), + typeof(TeachingTip), + new PropertyMetadata(default(Thickness), OnPlacementMarginPropertyChanged)); + + public Thickness PlacementMargin + { + get => (Thickness)GetValue(PlacementMarginProperty); + set => SetValue(PlacementMarginProperty, value); + } + + private static void OnPlacementMarginPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region PreferredPlacement + + public static readonly DependencyProperty PreferredPlacementProperty = + DependencyProperty.Register( + nameof(PreferredPlacement), + typeof(TeachingTipPlacementMode), + typeof(TeachingTip), + new PropertyMetadata(TeachingTipPlacementMode.Auto, OnPreferredPlacementPropertyChanged)); + + public TeachingTipPlacementMode PreferredPlacement + { + get => (TeachingTipPlacementMode)GetValue(PreferredPlacementProperty); + set => SetValue(PreferredPlacementProperty, value); + } + + private static void OnPreferredPlacementPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region ShouldConstrainToRootBounds + + public static readonly DependencyProperty ShouldConstrainToRootBoundsProperty = + DependencyProperty.Register( + nameof(ShouldConstrainToRootBounds), + typeof(bool), + typeof(TeachingTip), + new PropertyMetadata(true, OnShouldConstrainToRootBoundsPropertyChanged)); + + public bool ShouldConstrainToRootBounds + { + get => (bool)GetValue(ShouldConstrainToRootBoundsProperty); + set => SetValue(ShouldConstrainToRootBoundsProperty, value); + } + + private static void OnShouldConstrainToRootBoundsPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region Subtitle + + public static readonly DependencyProperty SubtitleProperty = + DependencyProperty.Register( + nameof(Subtitle), + typeof(string), + typeof(TeachingTip), + new PropertyMetadata(OnSubtitlePropertyChanged)); + + public string Subtitle + { + get => (string)GetValue(SubtitleProperty); + set => SetValue(SubtitleProperty, value); + } + + private static void OnSubtitlePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region TailVisibility + + public static readonly DependencyProperty TailVisibilityProperty = + DependencyProperty.Register( + nameof(TailVisibility), + typeof(TeachingTipTailVisibility), + typeof(TeachingTip), + new PropertyMetadata(TeachingTipTailVisibility.Auto, OnTailVisibilityPropertyChanged)); + + public TeachingTipTailVisibility TailVisibility + { + get => (TeachingTipTailVisibility)GetValue(TailVisibilityProperty); + set => SetValue(TailVisibilityProperty, value); + } + + private static void OnTailVisibilityPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region Target + + public static readonly DependencyProperty TargetProperty = + DependencyProperty.Register( + nameof(Target), + typeof(FrameworkElement), + typeof(TeachingTip), + new PropertyMetadata(OnTargetPropertyChanged)); + + public FrameworkElement Target + { + get => (FrameworkElement)GetValue(TargetProperty); + set => SetValue(TargetProperty, value); + } + + private static void OnTargetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region TemplateSettings + + public static readonly DependencyProperty TemplateSettingsProperty = + DependencyProperty.Register( + nameof(TemplateSettings), + typeof(TeachingTipTemplateSettings), + typeof(TeachingTip), + new PropertyMetadata(OnTemplateSettingsPropertyChanged)); + + public TeachingTipTemplateSettings TemplateSettings + { + get => (TeachingTipTemplateSettings)GetValue(TemplateSettingsProperty); + set => SetValue(TemplateSettingsProperty, value); + } + + private static void OnTemplateSettingsPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region Title + + public static readonly DependencyProperty TitleProperty = + DependencyProperty.Register( + nameof(Title), + typeof(string), + typeof(TeachingTip), + new PropertyMetadata(OnTitlePropertyChanged)); + + public string Title + { + get => (string)GetValue(TitleProperty); + set => SetValue(TitleProperty, value); + } + + private static void OnTitlePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + var owner = (TeachingTip)sender; + owner.OnPropertyChanged(args); + } + + #endregion + + #region CornerRadius + + public static readonly DependencyProperty CornerRadiusProperty = + ControlHelper.CornerRadiusProperty.AddOwner(typeof(TeachingTip)); + + public CornerRadius CornerRadius + { + get => (CornerRadius)GetValue(CornerRadiusProperty); + set => SetValue(CornerRadiusProperty, value); + } + + #endregion + + public event TypedEventHandler ActionButtonClick; + public event TypedEventHandler CloseButtonClick; + public event TypedEventHandler Closing; + public event TypedEventHandler Closed; + } +} diff --git a/ModernWpf.Controls/TeachingTip/TeachingTip.cs b/ModernWpf.Controls/TeachingTip/TeachingTip.cs index 6385f7c1..592ee84a 100644 --- a/ModernWpf.Controls/TeachingTip/TeachingTip.cs +++ b/ModernWpf.Controls/TeachingTip/TeachingTip.cs @@ -1,8 +1,2449 @@ -using System.Windows.Controls; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using System.Windows; +using System.Windows.Controls; namespace ModernWpf.Controls { - public class TeachingTip : ContentControl + public partial class TeachingTip : ContentControl { + // TeachingTip() + //{ + // __RP_Marker_ClassById(RuntimeProfiler.ProfId_TeachingTip); + // SetDefaultStyleKey(this); + // EnsureProperties(); + // Unloaded({ this, &ClosePopupOnUnloadEvent }); + // m_automationNameChangedRevoker = RegisterPropertyChanged(this, AutomationProperties.NameProperty(), { this, &OnAutomationNameChanged }); + // m_automationIdChangedRevoker = RegisterPropertyChanged(this, AutomationProperties.AutomationIdProperty(), { this, &OnAutomationIdChanged }); + // SetValue(s_TemplateSettingsProperty, make<.TeachingTipTemplateSettings>()); + // } + + // AutomationPeer OnCreateAutomationPeer() + // { + // return make(this); + // } + + // void OnApplyTemplate() + // { + // m_acceleratorKeyActivatedRevoker.revoke(); + // m_effectiveViewportChangedRevoker.revoke(); + // m_contentSizeChangedRevoker.revoke(); + // m_closeButtonClickedRevoker.revoke(); + // m_alternateCloseButtonClickedRevoker.revoke(); + // m_actionButtonClickedRevoker.revoke(); + // m_windowSizeChangedRevoker.revoke(); + + // IControlProtected controlProtected{ this }; + + // m_container.set(GetTemplateChildT(s_containerName, controlProtected)); + // m_rootElement.set(m_container.get().Child()); + // m_tailOcclusionGrid.set(GetTemplateChildT(s_tailOcclusionGridName, controlProtected)); + // m_contentRootGrid.set(GetTemplateChildT(s_contentRootGridName, controlProtected)); + // m_nonHeroContentRootGrid.set(GetTemplateChildT(s_nonHeroContentRootGridName, controlProtected)); + // m_heroContentBorder.set(GetTemplateChildT(s_heroContentBorderName, controlProtected)); + // m_actionButton.set(GetTemplateChildT