diff --git a/samples/ControlCatalog/Pages/ScreenPage.cs b/samples/ControlCatalog/Pages/ScreenPage.cs
index 3cd0521481..3d3ed00aac 100644
--- a/samples/ControlCatalog/Pages/ScreenPage.cs
+++ b/samples/ControlCatalog/Pages/ScreenPage.cs
@@ -13,6 +13,8 @@ namespace ControlCatalog.Pages
{
private double _leftMost;
+ protected override bool BypassFlowDirectionPolicies => true;
+
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
@@ -78,7 +80,5 @@ namespace ControlCatalog.Pages
return new FormattedText(textToFormat, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
Typeface.Default, 12, Brushes.Green);
}
-
- protected override bool ShouldPresentMirrored() => false;
}
}
diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs
index f209a07a31..cc2f79f574 100644
--- a/src/Avalonia.Controls/ComboBox.cs
+++ b/src/Avalonia.Controls/ComboBox.cs
@@ -183,12 +183,24 @@ namespace Avalonia.Controls
this.UpdateSelectionBoxItem(SelectedItem);
}
- // Because the SelectedItem isn't connected to the visual tree
+ // Because the SelectedItem and his children sometimes isn't connected
+ // to the visual tree and sometimes not to logical tree
public override void InvalidateFlowDirection()
{
+ base.InvalidateFlowDirection();
+
if (SelectedItem is Control selectedControl)
{
selectedControl.InvalidateFlowDirection();
+
+ foreach (var visual in selectedControl.GetVisualDescendants())
+ {
+ if (visual is Control childControl)
+ {
+ childControl.InvalidateFlowDirection();
+ }
+ }
+
foreach (var logical in selectedControl.GetLogicalDescendants())
{
if (logical is Control childControl)
@@ -197,8 +209,6 @@ namespace Avalonia.Controls
}
}
}
-
- base.InvalidateFlowDirection();
}
///
diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs
index 16c3b1d5dd..ab8d17fbdf 100644
--- a/src/Avalonia.Controls/Control.cs
+++ b/src/Avalonia.Controls/Control.cs
@@ -140,6 +140,17 @@ namespace Avalonia.Controls
///
bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null;
+ ///
+ /// Gets a value indicating whether control bypass FlowDirecton policies.
+ ///
+ ///
+ /// Related to FlowDirection system and returns false as default, so if
+ /// is RTL then control will get a mirror presentation.
+ /// For controls that want to avoid mirror presentation, it is possible to override
+ /// this property and return true.
+ ///
+ protected virtual bool BypassFlowDirectionPolicies => false;
+
///
void ISetterValue.Initialize(ISetter setter)
{
@@ -338,37 +349,34 @@ namespace Avalonia.Controls
///
/// Computes the value according to the
- ///
+ /// and
///
public virtual void InvalidateFlowDirection()
{
- bool parentShouldPresentMirrored = false;
- bool thisShouldPresentMirrored = ShouldPresentMirrored();
+ FlowDirection thisFD = this.FlowDirection;
+ FlowDirection parentFD = FlowDirection.LeftToRight;
+
+ bool thisBypassFlowDirectionPolicies = BypassFlowDirectionPolicies;
+ bool parentBypassFlowDirectionPolicies = false;
var parent = this.FindAncestorOfType();
if (parent != null)
{
- parentShouldPresentMirrored = parent.ShouldPresentMirrored();
+ parentFD = parent.FlowDirection;
+ parentBypassFlowDirectionPolicies = parent.BypassFlowDirectionPolicies;
}
else if (this.Parent is Control logicalParent)
{
- parentShouldPresentMirrored = logicalParent.ShouldPresentMirrored();
+ parentFD = logicalParent.FlowDirection;
+ parentBypassFlowDirectionPolicies = logicalParent.BypassFlowDirectionPolicies;
}
- bool shouldApplyMirrorTransform = thisShouldPresentMirrored != parentShouldPresentMirrored;
+ bool thisShouldBeMirrored = thisFD == FlowDirection.RightToLeft && !BypassFlowDirectionPolicies;
+ bool parentShouldBeMirrored = parentFD == FlowDirection.RightToLeft && !parentBypassFlowDirectionPolicies;
- IsMirrorTransform = shouldApplyMirrorTransform;
- }
+ bool shouldApplyMirrorTransform = thisShouldBeMirrored != parentShouldBeMirrored;
- ///
- /// Determines whether the element should be present mirrored, this
- /// method related to FlowDirection system and returns true if FlowDirection
- /// is RightToLeft. For controls that want to avoid this behavior, it is
- /// possible to override this method and return false.
- ///
- protected virtual bool ShouldPresentMirrored()
- {
- return FlowDirection == FlowDirection.RightToLeft;
+ IsMirrorTransform = shouldApplyMirrorTransform;
}
}
}
diff --git a/src/Avalonia.Controls/Image.cs b/src/Avalonia.Controls/Image.cs
index fa654f8ad1..7408bff902 100644
--- a/src/Avalonia.Controls/Image.cs
+++ b/src/Avalonia.Controls/Image.cs
@@ -66,6 +66,8 @@ namespace Avalonia.Controls
set { SetValue(StretchDirectionProperty, value); }
}
+ protected override bool BypassFlowDirectionPolicies => true;
+
///
/// Renders the control.
///
@@ -127,7 +129,5 @@ namespace Avalonia.Controls
return new Size();
}
}
-
- protected override bool ShouldPresentMirrored() => false;
}
}
diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
index 9b77b6ade1..5539afad46 100644
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -281,6 +281,8 @@ namespace Avalonia.Controls.Presenters
}
}
+ protected override bool BypassFlowDirectionPolicies => true;
+
///
/// Creates the used to render the text.
///
@@ -798,7 +800,5 @@ namespace Avalonia.Controls.Presenters
}
}
}
-
- protected override bool ShouldPresentMirrored() => false;
}
}
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index bf510014b5..49800e5760 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -329,6 +329,8 @@ namespace Avalonia.Controls
set => SetValue(TextDecorationsProperty, value);
}
+ protected override bool BypassFlowDirectionPolicies => true;
+
///
/// Gets the value of the attached on a control.
///
@@ -612,7 +614,5 @@ namespace Avalonia.Controls
{
InvalidateTextLayout();
}
-
- protected override bool ShouldPresentMirrored() => false;
}
}
diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs
index a54bcf3bff..9bc96805a5 100644
--- a/src/Avalonia.Controls/TopLevel.cs
+++ b/src/Avalonia.Controls/TopLevel.cs
@@ -348,6 +348,12 @@ namespace Avalonia.Controls
///
protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager(this);
+ public override void InvalidateFlowDirection()
+ {
+ }
+
+ protected override bool BypassFlowDirectionPolicies => true;
+
///
/// Handles a paint notification from .
///
@@ -529,11 +535,5 @@ namespace Avalonia.Controls
ITextInputMethodImpl? ITextInputMethodRoot.InputMethod =>
(PlatformImpl as ITopLevelImplWithTextInputMethod)?.TextInputMethod;
-
- public override void InvalidateFlowDirection()
- {
- }
-
- protected override bool ShouldPresentMirrored() => false;
}
}