mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-30 02:47:45 +08:00
完成二级菜单弹出
This commit is contained in:
parent
5a7cabdb6b
commit
5b6ba00df7
@ -10,13 +10,13 @@
|
||||
<showcase:ShowCasePanel>
|
||||
<atom:Menu>
|
||||
<atom:MenuItem Header="_File">
|
||||
<atom:MenuItem Header="New Text File" InputGesture="Ctrl+N" />
|
||||
<atom:MenuItem Header="New File" InputGesture="Ctrl+Alt+N" />
|
||||
<atom:MenuItem Header="New Window" InputGesture="Ctrl+Shift+N" />
|
||||
<atom:MenuItem Header="New Text File" InputGesture="Ctrl+N" ToggleType="Radio" GroupName="Group1"/>
|
||||
<atom:MenuItem Header="New File" InputGesture="Ctrl+Alt+N" ToggleType="Radio" GroupName="Group1"/>
|
||||
<atom:MenuItem Header="New Window" InputGesture="Ctrl+Shift+N" ToggleType="Radio" GroupName="Group1"/>
|
||||
<atom:MenuSeparator />
|
||||
<atom:MenuItem Header="Save" InputGesture="Ctrl+S" />
|
||||
<atom:MenuItem Header="Save As..." InputGesture="Ctrl+Shift+S" />
|
||||
<atom:MenuItem Header="Save All" InputGesture="Ctrl+K" />
|
||||
<atom:MenuItem Header="Save" InputGesture="Ctrl+S" ToggleType="CheckBox" />
|
||||
<atom:MenuItem Header="Save As..." InputGesture="Ctrl+Shift+S" ToggleType="CheckBox" Icon="{atom:IconProvider Kind=GithubOutlined}" />
|
||||
<atom:MenuItem Header="Save All" InputGesture="Ctrl+K" ToggleType="CheckBox" Icon="{atom:IconProvider Kind=CheckOutlined}"/>
|
||||
<atom:MenuSeparator />
|
||||
<atom:MenuItem Header="Exit" />
|
||||
</atom:MenuItem>
|
||||
|
@ -188,9 +188,10 @@ public class CheckBox : AvaloniaCheckBox,
|
||||
var checkMarkPenWidth = 2;
|
||||
var checkMarkPen = new Pen(IndicatorCheckedMarkBrush, 2);
|
||||
var checkMarkBounds = checkMarkGeometry.GetRenderBounds(checkMarkPen);
|
||||
var deltaSize = (CheckIndicatorSize - checkMarkBounds.Width) / 2;
|
||||
var offsetX = deltaSize - checkMarkPenWidth - penWidth;
|
||||
var offsetY = deltaSize - checkMarkPenWidth - penWidth;
|
||||
var deltaWidth = (CheckIndicatorSize - checkMarkBounds.Width) / 2;
|
||||
var deltaHeight = (CheckIndicatorSize - checkMarkBounds.Height) / 2;
|
||||
var offsetX = indicatorRect.X + deltaWidth - checkMarkPenWidth - penWidth;
|
||||
var offsetY = indicatorRect.Y + deltaHeight - checkMarkPenWidth - penWidth * 2;
|
||||
checkMarkGeometry.Transform = new TranslateTransform(offsetX, offsetY);
|
||||
context.DrawGeometry(null, checkMarkPen, checkMarkGeometry);
|
||||
} else if (_styleState.HasFlag(ControlStyleState.Indeterminate)) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.LogicalTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
19
src/AtomUI.Controls/Menu/MenuInteractionHandler.cs
Normal file
19
src/AtomUI.Controls/Menu/MenuInteractionHandler.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Avalonia.Controls.Platform;
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class MenuInteractionHandler : DefaultMenuInteractionHandler
|
||||
{
|
||||
public MenuInteractionHandler(bool isContextMenu)
|
||||
: base(isContextMenu)
|
||||
{
|
||||
}
|
||||
|
||||
public MenuInteractionHandler(bool isContextMenu,
|
||||
IInputManager? inputManager,
|
||||
Action<Action, TimeSpan> delayRun)
|
||||
: base(isContextMenu, inputManager, delayRun)
|
||||
{
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Media;
|
||||
using AtomUI.Media;
|
||||
using AtomUI.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
@ -11,7 +10,6 @@ using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@ -37,6 +35,9 @@ public class MenuItem : AvaloniaMenuItem, IControlCustomStyle
|
||||
|
||||
private readonly IControlCustomStyle _customStyle;
|
||||
private ContentPresenter? _topLevelContentPresenter;
|
||||
private ContentControl? _togglePresenter;
|
||||
private Popup? _popup;
|
||||
|
||||
internal static PlatformKeyGestureConverter KeyGestureConverter = new PlatformKeyGestureConverter();
|
||||
|
||||
static MenuItem()
|
||||
@ -72,7 +73,10 @@ public class MenuItem : AvaloniaMenuItem, IControlCustomStyle
|
||||
{
|
||||
if (IsTopLevel) {
|
||||
_topLevelContentPresenter = scope.Find<ContentPresenter>(TopLevelMenuItemTheme.HeaderPresenterPart);
|
||||
} else {
|
||||
_togglePresenter = scope.Find<ContentControl>(MenuItemTheme.TogglePresenterPart);
|
||||
}
|
||||
HandleToggleTypeChanged();
|
||||
_customStyle.SetupTransitions();
|
||||
UpdatePseudoClasses();
|
||||
}
|
||||
@ -89,6 +93,27 @@ public class MenuItem : AvaloniaMenuItem, IControlCustomStyle
|
||||
BindUtils.CreateTokenBinding(pathIcon, PathIcon.HeightProperty, MenuResourceKey.ItemIconSize);
|
||||
BindUtils.CreateTokenBinding(pathIcon, PathIcon.NormalFilledBrushProperty, MenuResourceKey.ItemColor);
|
||||
}
|
||||
} else if (e.Property == ToggleTypeProperty) {
|
||||
HandleToggleTypeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleToggleTypeChanged()
|
||||
{
|
||||
if (IsTopLevel || _togglePresenter is null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ToggleType == MenuItemToggleType.None) {
|
||||
if (_togglePresenter.Presenter is not null) {
|
||||
_togglePresenter.Presenter.IsVisible = false;
|
||||
}
|
||||
} else if (ToggleType == MenuItemToggleType.CheckBox) {
|
||||
_togglePresenter.Content = new CheckBox();
|
||||
_togglePresenter.IsVisible = true;
|
||||
} else if (ToggleType == MenuItemToggleType.Radio) {
|
||||
_togglePresenter.Content = new RadioButton();
|
||||
_togglePresenter.IsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ internal class MenuItemTheme : ControlTheme
|
||||
public const string ItemTextPresenterPart = "Part_ItemTextPresenter";
|
||||
public const string InputGestureTextPart = "Part_InputGestureText";
|
||||
public const string MenuIndicatorIconPart = "Part_MenuIndicatorIcon";
|
||||
public const string PopupPart = "PART_Popup";
|
||||
public const string ItemsPresenterPart = "PART_ItemsPresenter";
|
||||
|
||||
public MenuItemTheme()
|
||||
: base(typeof(MenuItem))
|
||||
@ -32,6 +34,8 @@ internal class MenuItemTheme : ControlTheme
|
||||
{
|
||||
return new FuncControlTemplate<MenuItem>((item, scope) =>
|
||||
{
|
||||
// 仅仅为了把 Popup 包进来,没有其他什么作用
|
||||
var layoutWrapper = new Panel();
|
||||
var container = new Border()
|
||||
{
|
||||
Name = ItemDecoratorPart
|
||||
@ -97,7 +101,8 @@ internal class MenuItemTheme : ControlTheme
|
||||
Name = ItemTextPresenterPart,
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
RecognizesAccessKey = true
|
||||
RecognizesAccessKey = true,
|
||||
IsHitTestVisible = false
|
||||
};
|
||||
Grid.SetColumn(itemTextPresenter, 2);
|
||||
BindUtils.CreateTokenBinding(itemTextPresenter, ContentPresenter.MarginProperty, MenuResourceKey.ItemMargin);
|
||||
@ -135,18 +140,59 @@ internal class MenuItemTheme : ControlTheme
|
||||
Grid.SetColumn(menuIndicatorIcon, 4);
|
||||
menuIndicatorIcon.RegisterInNameScope(scope);
|
||||
|
||||
var popup = CreateMenuPopup();
|
||||
|
||||
layout.Children.Add(togglePresenter);
|
||||
layout.Children.Add(iconPresenter);
|
||||
layout.Children.Add(itemTextPresenter);
|
||||
layout.Children.Add(inputGestureText);
|
||||
layout.Children.Add(menuIndicatorIcon);
|
||||
layout.Children.Add(popup);
|
||||
|
||||
container.Child = layout;
|
||||
|
||||
return container;
|
||||
layoutWrapper.Children.Add(container);
|
||||
return layoutWrapper;
|
||||
});
|
||||
}
|
||||
|
||||
private Popup CreateMenuPopup()
|
||||
{
|
||||
var popup = new Popup()
|
||||
{
|
||||
Name = PopupPart,
|
||||
WindowManagerAddShadowHint = false,
|
||||
IsLightDismissEnabled = false,
|
||||
Placement = PlacementMode.RightEdgeAlignedTop,
|
||||
};
|
||||
|
||||
var border = new Border();
|
||||
BindUtils.CreateTokenBinding(border, Border.BackgroundProperty, GlobalResourceKey.ColorBgContainer);
|
||||
BindUtils.CreateTokenBinding(border, Border.CornerRadiusProperty, MenuResourceKey.MenuPopupBorderRadius);
|
||||
BindUtils.CreateTokenBinding(border, Border.MinWidthProperty, MenuResourceKey.MenuPopupMinWidth);
|
||||
BindUtils.CreateTokenBinding(border, Border.MaxWidthProperty, MenuResourceKey.MenuPopupMaxWidth);
|
||||
BindUtils.CreateTokenBinding(border, Border.MinHeightProperty, MenuResourceKey.MenuPopupMinHeight);
|
||||
BindUtils.CreateTokenBinding(border, Border.MaxHeightProperty, MenuResourceKey.MenuPopupMaxHeight);
|
||||
BindUtils.CreateTokenBinding(border, Border.PaddingProperty, MenuResourceKey.MenuPopupContentPadding);
|
||||
|
||||
var scrollViewer = new MenuScrollViewer();
|
||||
var itemsPresenter = new ItemsPresenter
|
||||
{
|
||||
Name = ItemsPresenterPart,
|
||||
};
|
||||
CreateTemplateParentBinding(itemsPresenter, ItemsPresenter.ItemsPanelProperty, MenuItem.ItemsPanelProperty);
|
||||
Grid.SetIsSharedSizeScope(itemsPresenter, true);
|
||||
scrollViewer.Content = itemsPresenter;
|
||||
border.Child = scrollViewer;
|
||||
|
||||
popup.Child = border;
|
||||
|
||||
BindUtils.CreateTokenBinding(popup, Popup.MarginToAnchorProperty, MenuResourceKey.TopLevelItemPopupMarginToAnchor);
|
||||
BindUtils.CreateTokenBinding(popup, Popup.MaskShadowsProperty, MenuResourceKey.MenuPopupBoxShadows);
|
||||
CreateTemplateParentBinding(popup, Popup.IsOpenProperty, MenuItem.IsSubMenuOpenProperty, BindingMode.TwoWay);
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
|
@ -39,33 +39,35 @@ public class TopLevelMenuItemTheme : ControlTheme
|
||||
RecognizesAccessKey = true,
|
||||
};
|
||||
|
||||
// TODO 后面需要评估一下,能直接绑定到对象,是否还需要这样通过模板绑定
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty, MenuItem.HeaderProperty);
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentTemplateProperty, MenuItem.HeaderTemplateProperty);
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.CornerRadiusProperty, MenuItem.CornerRadiusProperty);
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.PaddingProperty, MenuItem.PaddingProperty);
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.MinHeightProperty, MenuItem.MinHeightProperty);
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.FontSizeProperty, MenuItem.FontSizeProperty);
|
||||
|
||||
contentPresenter.RegisterInNameScope(scope);
|
||||
panel.Children.Add(contentPresenter);
|
||||
|
||||
var popup = CreateMenuPopup(menuItem);
|
||||
var popup = CreateMenuPopup();
|
||||
panel.Children.Add(popup);
|
||||
return panel;
|
||||
});
|
||||
}
|
||||
|
||||
private Popup CreateMenuPopup(MenuItem menuItem)
|
||||
private Popup CreateMenuPopup()
|
||||
{
|
||||
var popup = new Popup()
|
||||
{
|
||||
Name = PopupPart,
|
||||
WindowManagerAddShadowHint = false,
|
||||
IsLightDismissEnabled = true,
|
||||
IsLightDismissEnabled = false,
|
||||
Placement = PlacementMode.BottomEdgeAlignedLeft,
|
||||
OverlayInputPassThroughElement = menuItem,
|
||||
};
|
||||
|
||||
var border = new Border();
|
||||
|
||||
BindUtils.CreateTokenBinding(border, Border.BackgroundProperty, GlobalResourceKey.ColorBgContainer);
|
||||
BindUtils.CreateTokenBinding(border, Border.CornerRadiusProperty, MenuResourceKey.MenuPopupBorderRadius);
|
||||
BindUtils.CreateTokenBinding(border, Border.MinWidthProperty, MenuResourceKey.MenuPopupMinWidth);
|
||||
|
@ -1,216 +0,0 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Automation.Peers;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Primitives.PopupPositioning;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform;
|
||||
using Avalonia.Styling;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// The root window of a <see cref="Popup"/>.
|
||||
/// </summary>
|
||||
public sealed class PopupRoot : WindowBase, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the <see cref="Transform"/> property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Transform?> TransformProperty =
|
||||
AvaloniaProperty.Register<PopupRoot, Transform?>(nameof(Transform));
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="WindowManagerAddShadowHint"/> property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<bool> WindowManagerAddShadowHintProperty =
|
||||
Popup.WindowManagerAddShadowHintProperty.AddOwner<PopupRoot>();
|
||||
|
||||
private PopupPositionerParameters _positionerParameters;
|
||||
internal PopupPositionerParameters PositionerParameters => _positionerParameters;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes static members of the <see cref="PopupRoot"/> class.
|
||||
/// </summary>
|
||||
static PopupRoot()
|
||||
{
|
||||
BackgroundProperty.OverrideDefaultValue(typeof(PopupRoot), Brushes.Transparent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PopupRoot"/> class.
|
||||
/// </summary>
|
||||
public PopupRoot(TopLevel parent, IPopupImpl impl)
|
||||
: this(parent, impl,null)
|
||||
{
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PopupRoot"/> class.
|
||||
/// </summary>
|
||||
/// <param name="parent">The popup parent.</param>
|
||||
/// <param name="impl">The popup implementation.</param>
|
||||
/// <param name="dependencyResolver">
|
||||
/// The dependency resolver to use. If null the default dependency resolver will be used.
|
||||
/// </param>
|
||||
public PopupRoot(TopLevel parent, IPopupImpl impl, IAvaloniaDependencyResolver? dependencyResolver)
|
||||
: base(impl, dependencyResolver)
|
||||
{
|
||||
ParentTopLevel = parent;
|
||||
impl.SetWindowManagerAddShadowHint(WindowManagerAddShadowHint);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the platform-specific window implementation.
|
||||
/// </summary>
|
||||
public new IPopupImpl? PlatformImpl => (IPopupImpl?)base.PlatformImpl;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a transform that will be applied to the popup.
|
||||
/// </summary>
|
||||
public Transform? Transform
|
||||
{
|
||||
get => GetValue(TransformProperty);
|
||||
set => SetValue(TransformProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a hint to the window manager that a shadow should be added to the popup.
|
||||
/// </summary>
|
||||
public bool WindowManagerAddShadowHint
|
||||
{
|
||||
get => GetValue(WindowManagerAddShadowHintProperty);
|
||||
set => SetValue(WindowManagerAddShadowHintProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent control in the event route.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Popup events are passed to their parent window. This facilitates this.
|
||||
/// </remarks>
|
||||
/// TODO 需要评估影响,可能有严重错误!!!
|
||||
//internal override Interactive? InteractiveParent => (Interactive?)Parent;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the control that is hosting the popup root.
|
||||
/// </summary>
|
||||
Visual? IHostedVisualTreeRoot.Host
|
||||
{
|
||||
get
|
||||
{
|
||||
// If the parent is attached to a visual tree, then return that. However the parent
|
||||
// will possibly be a standalone Popup (i.e. a Popup not attached to a visual tree,
|
||||
// created by e.g. a ContextMenu): if this is the case, return the ParentTopLevel
|
||||
// if set. This helps to allow the focus manager to restore the focus to the outer
|
||||
// scope when the popup is closed.
|
||||
var parentVisual = Parent as Visual;
|
||||
if (parentVisual?.GetVisualRoot() is not null)
|
||||
return parentVisual;
|
||||
return ParentTopLevel ?? parentVisual;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the styling parent of the popup root.
|
||||
/// </summary>
|
||||
IStyleHost? IStyleHost.StylingParent => Parent;
|
||||
|
||||
public TopLevel ParentTopLevel { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
PlatformImpl?.Dispose();
|
||||
}
|
||||
|
||||
private void UpdatePosition()
|
||||
{
|
||||
PlatformImpl?.PopupPositioner?.Update(_positionerParameters);
|
||||
}
|
||||
|
||||
public void ConfigurePosition(Visual target, PlacementMode placement, Point offset,
|
||||
PopupAnchor anchor = PopupAnchor.None,
|
||||
PopupGravity gravity = PopupGravity.None,
|
||||
PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All,
|
||||
Rect? rect = null)
|
||||
{
|
||||
_positionerParameters.ConfigurePosition(ParentTopLevel, target,
|
||||
placement, offset, anchor, gravity, constraintAdjustment, rect, FlowDirection);
|
||||
|
||||
if (_positionerParameters.Size != default) {
|
||||
UpdatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetChild(Control? control) => Content = control;
|
||||
|
||||
Visual IPopupHost.HostedVisualTreeRoot => this;
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var maxAutoSize = PlatformImpl?.MaxAutoSizeHint ?? Size.Infinity;
|
||||
var constraint = availableSize;
|
||||
|
||||
if (double.IsInfinity(constraint.Width))
|
||||
{
|
||||
constraint = constraint.WithWidth(maxAutoSize.Width);
|
||||
}
|
||||
|
||||
if (double.IsInfinity(constraint.Height))
|
||||
{
|
||||
constraint = constraint.WithHeight(maxAutoSize.Height);
|
||||
}
|
||||
|
||||
var measured = base.MeasureOverride(constraint);
|
||||
var width = measured.Width;
|
||||
var height = measured.Height;
|
||||
var widthCache = Width;
|
||||
var heightCache = Height;
|
||||
|
||||
if (!double.IsNaN(widthCache))
|
||||
{
|
||||
width = widthCache;
|
||||
}
|
||||
|
||||
width = Math.Min(width, MaxWidth);
|
||||
width = Math.Max(width, MinWidth);
|
||||
|
||||
if (!double.IsNaN(heightCache))
|
||||
{
|
||||
height = heightCache;
|
||||
}
|
||||
|
||||
height = Math.Min(height, MaxHeight);
|
||||
height = Math.Max(height, MinHeight);
|
||||
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
protected override sealed Size ArrangeSetBounds(Size size)
|
||||
{
|
||||
_positionerParameters.Size = size;
|
||||
UpdatePosition();
|
||||
return ClientSize;
|
||||
}
|
||||
|
||||
protected override AutomationPeer OnCreateAutomationPeer()
|
||||
{
|
||||
return new PopupRootAutomationPeer(this);
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (change.Property == WindowManagerAddShadowHintProperty)
|
||||
{
|
||||
PlatformImpl?.SetWindowManagerAddShadowHint(change.GetNewValue<bool>());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
using Avalonia.Automation.Peers;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class PopupRootAutomationPeer : WindowBaseAutomationPeer
|
||||
{
|
||||
public PopupRootAutomationPeer(PopupRoot owner)
|
||||
: base(owner)
|
||||
{
|
||||
if (owner.IsVisible) {
|
||||
StartTrackingFocus();
|
||||
} else {
|
||||
owner.Opened += OnOpened;
|
||||
}
|
||||
owner.Closed += OnClosed;
|
||||
}
|
||||
|
||||
protected override bool IsContentElementCore() => false;
|
||||
protected override bool IsControlElementCore() => false;
|
||||
|
||||
|
||||
protected override AutomationPeer? GetParentCore()
|
||||
{
|
||||
var parent = base.GetParentCore();
|
||||
return parent;
|
||||
}
|
||||
|
||||
private void OnOpened(object? sender, EventArgs e)
|
||||
{
|
||||
((PopupRoot)Owner).Opened -= OnOpened;
|
||||
StartTrackingFocus();
|
||||
}
|
||||
|
||||
private void OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
((PopupRoot)Owner).Closed -= OnClosed;
|
||||
StopTrackingFocus();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user