Browse Source

fix ComboBox and start working Popup

pull/7810/head
daniel mayost 5 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.Layout;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using Avalonia.LogicalTree;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -182,6 +183,24 @@ namespace Avalonia.Controls
this.UpdateSelectionBoxItem(SelectedItem); 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/> /// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {

40
src/Avalonia.Controls/Control.cs

@ -190,6 +190,7 @@ namespace Avalonia.Controls
{ {
base.OnAttachedToVisualTreeCore(e); base.OnAttachedToVisualTreeCore(e);
InvalidateFlowDirection();
InitializeIfNeeded(); InitializeIfNeeded();
} }
@ -317,25 +318,29 @@ namespace Avalonia.Controls
if (change.Property == FlowDirectionProperty) if (change.Property == FlowDirectionProperty)
{ {
// A change in value inherited should be prevented from calling this method // 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) if (GetBaseValue(FlowDirectionProperty, change.Priority).HasValue)
{ {
InvalidateFlowDirection(); InvalidateFlowDirection();
NotifyDescendantFlowDirection();
foreach (var visual in this.GetVisualDescendants())
{
if (visual is Control child)
{
child.InvalidateFlowDirection();
}
}
InvalidateVisual(); InvalidateVisual();
} }
} }
} }
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) /// <summary>
{ /// Computes the <see cref="IVisual.IsMirrorTransform"/> value according to the
base.OnAttachedToVisualTree(e); /// <see cref="FlowDirection"/>
/// </summary>
InvalidateFlowDirection(); public virtual void InvalidateFlowDirection()
}
private void InvalidateFlowDirection()
{ {
bool parentShouldPresentedMirrored = false; bool parentShouldPresentedMirrored = false;
bool thisShouldPresentedMirrored = ShouldPresentedMirrored(); bool thisShouldPresentedMirrored = ShouldPresentedMirrored();
@ -345,23 +350,16 @@ namespace Avalonia.Controls
{ {
parentShouldPresentedMirrored = parent.ShouldPresentedMirrored(); parentShouldPresentedMirrored = parent.ShouldPresentedMirrored();
} }
else if (this.Parent is Control logicalParent)
{
parentShouldPresentedMirrored = logicalParent.ShouldPresentedMirrored();
}
bool shouldApplyMirrorTransform = thisShouldPresentedMirrored != parentShouldPresentedMirrored; bool shouldApplyMirrorTransform = thisShouldPresentedMirrored != parentShouldPresentedMirrored;
IsMirrorTransform = shouldApplyMirrorTransform; IsMirrorTransform = shouldApplyMirrorTransform;
} }
private void NotifyDescendantFlowDirection()
{
foreach (var visual in this.GetVisualDescendants())
{
if (visual is Control child)
{
child.InvalidateFlowDirection();
}
}
}
/// <summary> /// <summary>
/// Determines whether the element should be presented mirrored, this /// Determines whether the element should be presented mirrored, this
/// method related to FlowDirection system and returns true if FlowDirection /// 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.Interactivity;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using Avalonia.Media;
using Avalonia.Controls.Primitives.PopupPositioning;
namespace Avalonia.Controls 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> /// <summary>
/// Called when the <see cref="MenuItem"/> is clicked. /// Called when the <see cref="MenuItem"/> is clicked.
/// </summary> /// </summary>
@ -493,6 +522,8 @@ namespace Avalonia.Controls
_popup.Opened += PopupOpened; _popup.Opened += PopupOpened;
_popup.Closed += PopupClosed; _popup.Closed += PopupClosed;
} }
InvalidateFlowDirection();
} }
protected override AutomationPeer OnCreateAutomationPeer() protected override AutomationPeer OnCreateAutomationPeer()

4
src/Avalonia.Controls/TopLevel.cs

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

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

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

2
src/Avalonia.Visuals/Visual.cs

@ -227,7 +227,7 @@ namespace Avalonia
} }
/// <summary> /// <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> /// </summary>
public bool IsMirrorTransform public bool IsMirrorTransform
{ {

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

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

Loading…
Cancel
Save