Browse Source

fix ComboBox and start working Popup

pull/7810/head
daniel mayost 4 years ago
parent
commit
8e9ec700b2
  1. 19
      src/Avalonia.Controls/ComboBox.cs
  2. 40
      src/Avalonia.Controls/Control.cs
  3. 31
      src/Avalonia.Controls/MenuItem.cs
  4. 4
      src/Avalonia.Controls/TopLevel.cs
  5. 2
      src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml
  6. 2
      src/Avalonia.Visuals/Visual.cs
  7. 2
      src/Avalonia.Visuals/VisualTree/IVisual.cs

19
src/Avalonia.Controls/ComboBox.cs

@ -13,6 +13,7 @@ using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.VisualTree;
using Avalonia.LogicalTree;
namespace Avalonia.Controls
{
@ -182,6 +183,24 @@ namespace Avalonia.Controls
this.UpdateSelectionBoxItem(SelectedItem);
}
// Because the SelectedItem isn't connected to the visual tree
public override void InvalidateFlowDirection()
{
if (SelectedItem is Control selectedControl)
{
selectedControl.InvalidateFlowDirection();
foreach (var logical in selectedControl.GetLogicalDescendants())
{
if (logical is Control childControl)
{
childControl.InvalidateFlowDirection();
}
}
}
base.InvalidateFlowDirection();
}
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{

40
src/Avalonia.Controls/Control.cs

@ -190,6 +190,7 @@ namespace Avalonia.Controls
{
base.OnAttachedToVisualTreeCore(e);
InvalidateFlowDirection();
InitializeIfNeeded();
}
@ -317,25 +318,29 @@ namespace Avalonia.Controls
if (change.Property == FlowDirectionProperty)
{
// A change in value inherited should be prevented from calling this method
// Because it will be handled from here by NotifyDescendantFlowDirection
// because it will be handled from here
if (GetBaseValue(FlowDirectionProperty, change.Priority).HasValue)
{
InvalidateFlowDirection();
NotifyDescendantFlowDirection();
foreach (var visual in this.GetVisualDescendants())
{
if (visual is Control child)
{
child.InvalidateFlowDirection();
}
}
InvalidateVisual();
}
}
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
InvalidateFlowDirection();
}
private void InvalidateFlowDirection()
/// <summary>
/// Computes the <see cref="IVisual.IsMirrorTransform"/> value according to the
/// <see cref="FlowDirection"/>
/// </summary>
public virtual void InvalidateFlowDirection()
{
bool parentShouldPresentedMirrored = false;
bool thisShouldPresentedMirrored = ShouldPresentedMirrored();
@ -345,23 +350,16 @@ namespace Avalonia.Controls
{
parentShouldPresentedMirrored = parent.ShouldPresentedMirrored();
}
else if (this.Parent is Control logicalParent)
{
parentShouldPresentedMirrored = logicalParent.ShouldPresentedMirrored();
}
bool shouldApplyMirrorTransform = thisShouldPresentedMirrored != parentShouldPresentedMirrored;
IsMirrorTransform = shouldApplyMirrorTransform;
}
private void NotifyDescendantFlowDirection()
{
foreach (var visual in this.GetVisualDescendants())
{
if (visual is Control child)
{
child.InvalidateFlowDirection();
}
}
}
/// <summary>
/// Determines whether the element should be presented mirrored, this
/// method related to FlowDirection system and returns true if FlowDirection

31
src/Avalonia.Controls/MenuItem.cs

@ -14,6 +14,8 @@ using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
using Avalonia.Media;
using Avalonia.Controls.Primitives.PopupPositioning;
namespace Avalonia.Controls
{
@ -409,6 +411,33 @@ namespace Avalonia.Controls
}
}
public override void InvalidateFlowDirection()
{
if (_popup != null && Parent is Menu)
{
var popupAnchor = FlowDirection == FlowDirection.LeftToRight ?
PopupAnchor.BottomLeft : PopupAnchor.BottomRight;
var popupGravity = FlowDirection == FlowDirection.LeftToRight ?
PopupGravity.BottomRight : PopupGravity.BottomLeft;
var placement = FlowDirection == FlowDirection.LeftToRight ?
PlacementMode.Right : PlacementMode.Left;
_popup.PlacementAnchor = popupAnchor;
_popup.PlacementGravity = popupGravity;
}
else if (_popup != null)
{
var placement = FlowDirection == FlowDirection.LeftToRight ?
PlacementMode.Right : PlacementMode.Left;
_popup.PlacementMode = placement;
}
base.InvalidateFlowDirection();
}
/// <summary>
/// Called when the <see cref="MenuItem"/> is clicked.
/// </summary>
@ -493,6 +522,8 @@ namespace Avalonia.Controls
_popup.Opened += PopupOpened;
_popup.Closed += PopupClosed;
}
InvalidateFlowDirection();
}
protected override AutomationPeer OnCreateAutomationPeer()

4
src/Avalonia.Controls/TopLevel.cs

@ -530,6 +530,10 @@ namespace Avalonia.Controls
ITextInputMethodImpl? ITextInputMethodRoot.InputMethod =>
(PlatformImpl as ITopLevelImplWithTextInputMethod)?.TextInputMethod;
public override void InvalidateFlowDirection()
{
}
protected override bool ShouldPresentedMirrored() => false;
}
}

2
src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

@ -111,7 +111,6 @@
</Border>
<Popup Name="PART_Popup"
WindowManagerAddShadowHint="False"
PlacementMode="Right"
HorizontalOffset="{DynamicResource MenuFlyoutSubItemPopupHorizontalOffset}"
IsLightDismissEnabled="False"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
@ -160,6 +159,7 @@
</ContentPresenter>
<Popup Name="PART_Popup"
WindowManagerAddShadowHint="False"
PlacementMode="AnchorAndGravity"
MinWidth="{ReflectionBinding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
IsLightDismissEnabled="True"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}"

2
src/Avalonia.Visuals/Visual.cs

@ -227,7 +227,7 @@ namespace Avalonia
}
/// <summary>
/// Gets or sets a value indicating whether this control presented as mirror.
/// Gets or sets a value indicating whether to apply mirror transform on this control.
/// </summary>
public bool IsMirrorTransform
{

2
src/Avalonia.Visuals/VisualTree/IVisual.cs

@ -76,7 +76,7 @@ namespace Avalonia.VisualTree
IBrush? OpacityMask { get; set; }
/// <summary>
/// Gets a value indicating whether this control presented as mirror.
/// Gets a value indicating whether to apply mirror transform on this control.
/// </summary>
bool IsMirrorTransform { get; }

Loading…
Cancel
Save