[C] Set binding context on Span Gestures (#3639)

* [Core] Set binding context on Span Gestures
* [Core] Simplify loop setting child binding context

- fixes #3524
This commit is contained in:
Shane Neuville 2018-08-24 01:50:47 -06:00 коммит произвёл Stephane Delcroix
Родитель 1584aa2ccc
Коммит 4222ad2542
6 изменённых файлов: 114 добавлений и 34 удалений

Просмотреть файл

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 3524, "ICommand binding from a TapGestureRecognizer on a Span doesn't work")]
#if UITEST
[NUnit.Framework.Category(UITestCategories.Gestures)]
#endif
public class Issue3524 : TestContentPage
{
const string kText = "Click Me To Increment";
public Command TapCommand { get; set; }
public String Text { get; set; } = kText;
protected override void Init()
{
int i = 0;
FormattedString formattedString = new FormattedString();
var span = new Span() { AutomationId = kText };
span.Text = kText;
var tapGesture = new TapGestureRecognizer();
tapGesture.SetBinding(TapGestureRecognizer.CommandProperty, "TapCommand");
span.GestureRecognizers.Add(tapGesture);
formattedString.Spans.Add(span);
BindingContext = this;
var label = new Label()
{
AutomationId = kText,
HorizontalOptions = LayoutOptions.Center
};
label.FormattedText = formattedString;
TapCommand = new Command(() =>
{
i++;
span.Text = $"{kText}: {i}";
});
Content = new ContentView()
{
Content = new StackLayout()
{
Children =
{
label
}
}
};
}
#if UITEST
[Test]
public void SpanGestureCommand()
{
RunningApp.WaitForElement(kText);
RunningApp.Tap(kText);
RunningApp.WaitForElement($"{kText}: 1");
}
#endif
}
}

Просмотреть файл

@ -8,7 +8,8 @@
<PropertyGroup Label="Configuration">
<Import_RootNamespace>Xamarin.Forms.Controls.Issues</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Issue3524.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2004.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3333.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2338.cs" />

Просмотреть файл

@ -1,10 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Xamarin.Forms
{
public static class BindableObjectExtensions
{
internal static void PropagateBindingContext<T>(this BindableObject self, IList<T> children)
{
PropagateBindingContext(self, children, BindableObject.SetInheritedBindingContext);
}
internal static void PropagateBindingContext<T>(this BindableObject self, IList<T> children, Action<BindableObject, object> setChildBindingContext)
{
if (children == null || children.Count == 0)
return;
var bc = self.BindingContext;
for (var i = 0; i < children.Count; i++)
{
var bo = children[i] as BindableObject;
if (bo == null)
continue;
setChildBindingContext(bo, bc);
}
}
public static void SetBinding(this BindableObject self, BindableProperty targetProperty, string path, BindingMode mode = BindingMode.Default, IValueConverter converter = null,
string stringFormat = null)
{

Просмотреть файл

@ -319,21 +319,10 @@ namespace Xamarin.Forms
protected override void OnBindingContextChanged()
{
var gotBindingContext = false;
object bc = null;
for (var index = 0; index < LogicalChildrenInternal.Count; index++)
this.PropagateBindingContext(LogicalChildrenInternal, (child, bc) =>
{
Element child = LogicalChildrenInternal[index];
if (!gotBindingContext)
{
bc = BindingContext;
gotBindingContext = true;
}
SetChildInheritedBindingContext(child, bc);
}
SetChildInheritedBindingContext((Element)child, bc);
});
if (_bindableResources != null)
foreach (BindableObject item in _bindableResources)

Просмотреть файл

@ -95,11 +95,18 @@ namespace Xamarin.Forms
set { SetValue(FontElement.FontSizeProperty, value); }
}
public double LineHeight {
public double LineHeight
{
get { return (double)GetValue(LineHeightElement.LineHeightProperty); }
set { SetValue(LineHeightElement.LineHeightProperty, value); }
}
protected override void OnBindingContextChanged()
{
this.PropagateBindingContext(GestureRecognizers);
base.OnBindingContextChanged();
}
void IFontElement.OnFontFamilyChanged(string oldValue, string newValue)
{
}

Просмотреть файл

@ -154,24 +154,7 @@ namespace Xamarin.Forms
protected override void OnBindingContextChanged()
{
var gotBindingContext = false;
object bc = null;
for (var i = 0; i < GestureRecognizers.Count; i++)
{
var bo = GestureRecognizers[i] as BindableObject;
if (bo == null)
continue;
if (!gotBindingContext)
{
bc = BindingContext;
gotBindingContext = true;
}
SetInheritedBindingContext(bo, bc);
}
this.PropagateBindingContext(GestureRecognizers);
base.OnBindingContextChanged();
}