using System.Windows.Controls.Primitives; // ReSharper disable once CheckNamespace namespace WPFluent.Controls; /// /// Represents a control that creates a pop-up window that displays information for an element in the interface. /// [TemplatePart(Name = "PART_Popup", Type = typeof(Popup))] public class Flyout : System.Windows.Controls.ContentControl { private const string ElementPopup = "PART_Popup"; /// /// Identifies the routed event. /// public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent( nameof(Closed), RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(Flyout)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register( nameof(IsOpen), typeof(bool), typeof(Flyout), new PropertyMetadata(false)); /// /// Identifies the routed event. /// public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent( nameof(Opened), RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(Flyout)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty PlacementProperty = DependencyProperty.Register( nameof(Placement), typeof(PlacementMode), typeof(Flyout), new PropertyMetadata(PlacementMode.Top)); private Popup _popup = default; /// /// Event triggered when is opened. /// public event TypedEventHandler Closed { add => AddHandler(ClosedEvent, value); remove => RemoveHandler(ClosedEvent, value); } /// /// Event triggered when is opened. /// public event TypedEventHandler Opened { add => AddHandler(OpenedEvent, value); remove => RemoveHandler(OpenedEvent, value); } protected virtual void OnPopupClosed(object sender, EventArgs e) { Hide(); RaiseEvent(new RoutedEventArgs(ClosedEvent, this)); } protected virtual void OnPopupOpened(object sender, EventArgs e) { RaiseEvent(new RoutedEventArgs(OpenedEvent, this)); } public void Hide() { if(IsOpen) { SetCurrentValue(IsOpenProperty, false); } } /// /// Invoked whenever application code or an internal process, such as a rebuilding layout pass, calls the /// ApplyTemplate method. /// public override void OnApplyTemplate() { base.OnApplyTemplate(); _popup = GetTemplateChild(ElementPopup) as Popup; if(_popup is null) { return; } _popup.Opened -= OnPopupOpened; _popup.Opened += OnPopupOpened; _popup.Closed -= OnPopupClosed; _popup.Closed += OnPopupClosed; } public void Show() { if(!IsOpen) { SetCurrentValue(IsOpenProperty, true); } } /// /// Gets or sets a value indicating whether a is visible. /// public bool IsOpen { get => (bool)GetValue(IsOpenProperty); set => SetValue(IsOpenProperty, value); } /// /// Gets or sets the orientation of the control when the control opens, and specifies the /// behavior of the control when it overlaps screen /// boundaries. /// [Bindable(true)] [Category("Layout")] public PlacementMode Placement { get => (PlacementMode)GetValue(PlacementProperty); set => SetValue(PlacementProperty, value); } }