Strongly typed handler option and standardize mappers a bit more (#12198)
* strongly typed handler option * - clean up from meeting notes * - make spacing consistent * - PR comments
This commit is contained in:
Родитель
8994f08adb
Коммит
66ab07a387
|
@ -2,22 +2,32 @@
|
|||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS')) != true ">
|
||||
<Compile Remove="**\*.iOS.cs" />
|
||||
<None Include="**\*.iOS.cs" />
|
||||
<Compile Remove="**\iOS\*.cs" />
|
||||
<None Include="**\iOS\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac')) != true ">
|
||||
<Compile Remove="**\*.Mac.cs" />
|
||||
<None Include="**\*.Mac.cs" />
|
||||
<Compile Remove="**\Mac\*.cs" />
|
||||
<None Include="**\Mac\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac')) != true And $(TargetFramework.StartsWith('Xamarin.iOS')) != true ">
|
||||
<Compile Remove="**\*.MaciOS.cs" />
|
||||
<None Include="**\*.MaciOS.cs" />
|
||||
<Compile Remove="**\MaciOS\*.cs" />
|
||||
<None Include="**\MaciOS\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('MonoAndroid')) != true ">
|
||||
<Compile Remove="**\*.Android.cs" />
|
||||
<None Include="**\*.Android.cs" />
|
||||
<Compile Remove="**\Android\*.cs" />
|
||||
<None Include="**\Android\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('netstandard')) != true ">
|
||||
<Compile Remove="**\*.Standard.cs" />
|
||||
<None Include="**\*.Standard.cs" />
|
||||
<Compile Remove="**\Standard\*.cs" />
|
||||
<None Include="**\Standard\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith('netcoreapp')) != true ">
|
||||
<Compile Remove="**\*.Win32.cs" />
|
||||
|
@ -26,13 +36,10 @@
|
|||
<None Include="**\*.xaml.cs" />
|
||||
<Compile Remove="**\*.xaml" />
|
||||
<None Include="**\*.xaml" />
|
||||
<Compile Remove="**\Win32\*.cs" />
|
||||
<None Include="**\Win32\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Platform\MaciOS\" />
|
||||
<Folder Include="Platform\iOS\" />
|
||||
<Folder Include="Platform\Mac\" />
|
||||
<Folder Include="Platform\Android\" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith('netcoreapp')) == true ">
|
||||
<UseWpf>true</UseWpf>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace Sample.Droid
|
|||
{
|
||||
foreach (var view in views)
|
||||
{
|
||||
_page.AddView(view.ToNative(this), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
|
||||
_page.AddView(view.ToNative(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Sample
|
|||
|
||||
public IView CreateView()
|
||||
{
|
||||
return new Button() { Text = "Hello I'm a button", BackgroundColor = Color.Purple };
|
||||
return new Button() { Color = Color.Green , Text = "Hello I'm a button", BackgroundColor = Color.Purple };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Xamarin.Platform.Handlers;
|
||||
|
||||
namespace Xamarin.Platform
|
||||
{
|
||||
public class ActionMapper<TVirtualView>
|
||||
public class ActionMapper<TVirtualView, TViewHandler>
|
||||
where TVirtualView : IFrameworkElement
|
||||
where TViewHandler : IViewHandler
|
||||
{
|
||||
public ActionMapper(PropertyMapper<TVirtualView> propertyMapper)
|
||||
public ActionMapper(PropertyMapper<TVirtualView, TViewHandler> propertyMapper)
|
||||
{
|
||||
PropertyMapper = propertyMapper;
|
||||
}
|
||||
|
||||
public PropertyMapper<TVirtualView> PropertyMapper { get; }
|
||||
public PropertyMapper<TVirtualView, TViewHandler> PropertyMapper { get; }
|
||||
|
||||
public Action<IViewHandler, TVirtualView> this[string key]
|
||||
public Action<TViewHandler, TVirtualView> this[string key]
|
||||
{
|
||||
set => PropertyMapper._mapper[key] = ((r, v) => value?.Invoke(r, (TVirtualView)v), false);
|
||||
set => PropertyMapper._mapper[key] = ((r, v) => value?.Invoke((TViewHandler)r, (TVirtualView)v), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Platform
|
||||
{
|
||||
public interface ILabel : IText
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using AndroidX.Core.View;
|
||||
using AndroidX.AppCompat.Widget;
|
||||
|
||||
|
||||
namespace Xamarin.Platform.Handlers
|
||||
{
|
||||
public partial class ButtonHandler : AbstractViewHandler<IButton, AppCompatButton>
|
||||
{
|
||||
protected override AppCompatButton CreateView() => new AppCompatButton(Context);
|
||||
|
||||
public static void MapText(IViewHandler handler, IButton view)
|
||||
{
|
||||
((AppCompatButton)handler.NativeView).Text = view.Text;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
using AppKit;
|
||||
|
||||
namespace Xamarin.Platform.Handlers
|
||||
{
|
||||
public partial class ButtonHandler : AbstractViewHandler<IButton, NSButton>
|
||||
{
|
||||
protected override NSButton CreateView() => throw new NotImplementedException();
|
||||
|
||||
public static void MapText(IViewHandler handler, IButton view) { }
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Platform.Handlers
|
||||
{
|
||||
public partial class ButtonHandler : AbstractViewHandler<IButton, object>
|
||||
{
|
||||
public static void MapText(IViewHandler handler, IButton view) { }
|
||||
|
||||
protected override object CreateView() => throw new NotImplementedException();
|
||||
}
|
||||
}
|
|
@ -1,21 +1,42 @@
|
|||
using System;
|
||||
#if __IOS__
|
||||
using NativeView = UIKit.UIButton;
|
||||
#elif __MACOS__
|
||||
using NativeView = AppKit.NSButton;
|
||||
#elif MONOANDROID
|
||||
using NativeView = AndroidX.AppCompat.Widget.AppCompatButton;
|
||||
#elif NETCOREAPP
|
||||
using NativeView = System.Windows.Controls.Button;
|
||||
#elif NETSTANDARD
|
||||
using NativeView = System.Object;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Platform.Handlers
|
||||
{
|
||||
public partial class ButtonHandler
|
||||
public partial class ButtonHandler : AbstractViewHandler<IButton, NativeView>
|
||||
{
|
||||
public static PropertyMapper<IButton> ButtonMapper = new PropertyMapper<IButton>(ViewHandler.ViewMapper)
|
||||
public static PropertyMapper<IButton, ButtonHandler> ButtonMapper = new PropertyMapper<IButton, ButtonHandler>(ViewHandler.ViewMapper)
|
||||
{
|
||||
[nameof(IButton.Text)] = MapText,
|
||||
Actions = {
|
||||
["DemoAction"] = DemoAction
|
||||
}
|
||||
[nameof(IButton.Color)] = MapColor
|
||||
};
|
||||
|
||||
private static void DemoAction(IViewHandler arg1, IButton arg2)
|
||||
public static void MapColor(ButtonHandler handler, IButton button)
|
||||
{
|
||||
handler.TypedNativeView.UpdateColor(button);
|
||||
}
|
||||
|
||||
public static void MapText(ButtonHandler handler, IButton button)
|
||||
{
|
||||
handler.TypedNativeView.UpdateText(button);
|
||||
}
|
||||
|
||||
#if MONOANDROID
|
||||
protected override NativeView CreateView() => new NativeView(this.Context);
|
||||
#else
|
||||
protected override NativeView CreateView() => new NativeView();
|
||||
#endif
|
||||
|
||||
public ButtonHandler() : base(ButtonMapper)
|
||||
{
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Xamarin.Platform.Handlers
|
||||
{
|
||||
public partial class ButtonHandler : AbstractViewHandler<IButton, UIButton>
|
||||
{
|
||||
protected override UIButton CreateView() => new UIButton();
|
||||
|
||||
public static void MapText(IViewHandler handler, IButton view)
|
||||
{
|
||||
((UIButton)handler.NativeView).SetText(view.Text);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
#if __IOS__
|
||||
using NativeView = UIKit.UILabel;
|
||||
#elif __MACOS__
|
||||
using NativeView = AppKit.NSTextField;
|
||||
#elif MONOANDROID
|
||||
using NativeView = Android.Widget.TextView;
|
||||
#elif NETCOREAPP
|
||||
using NativeView = System.Windows.Controls.TextBlock;
|
||||
#elif NETSTANDARD
|
||||
using NativeView = System.Object;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Platform.Handlers
|
||||
{
|
||||
public partial class LabelHandler : AbstractViewHandler<ILabel, NativeView>
|
||||
{
|
||||
public static PropertyMapper<ILabel, LabelHandler> LabelMapper = new PropertyMapper<ILabel, LabelHandler>(ViewHandler.ViewMapper)
|
||||
{
|
||||
[nameof(ILabel.Color)] = MapColor
|
||||
};
|
||||
|
||||
public static void MapColor(LabelHandler handler, ILabel Label)
|
||||
{
|
||||
}
|
||||
|
||||
#if MONOANDROID
|
||||
protected override NativeView CreateView() => new NativeView(this.Context);
|
||||
#else
|
||||
protected override NativeView CreateView() => new NativeView();
|
||||
#endif
|
||||
|
||||
public LabelHandler() : base(LabelMapper)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public LabelHandler(PropertyMapper mapper) : base(mapper ?? LabelMapper)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AndroidX.AppCompat.Widget;
|
||||
|
||||
namespace Xamarin.Platform
|
||||
{
|
||||
public static class ButtonExtensions
|
||||
{
|
||||
public static void UpdateColor(this AppCompatButton appCompatButton, IButton button) =>
|
||||
appCompatButton.SetTextColor(button.Color.ToNative());
|
||||
|
||||
public static void UpdateText(this AppCompatButton appCompatButton, IButton button) =>
|
||||
appCompatButton.Text = button.Text;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AndroidX.AppCompat.Widget;
|
||||
|
||||
namespace Xamarin.Platform
|
||||
{
|
||||
public static class ButtonExtensions
|
||||
{
|
||||
public static void UpdateColor(this IButton button, NSButton button)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Platform
|
||||
{
|
||||
public static class ButtonExtensions
|
||||
{
|
||||
public static void UpdateColor(this object nothing, IButton button)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static void UpdateText(this object nothing, IButton button)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UIKit;
|
||||
|
||||
namespace Xamarin.Platform
|
||||
{
|
||||
public static class ButtonExtensions
|
||||
{
|
||||
public static void UpdateColor(this UIButton nativeButton, IButton button)
|
||||
{
|
||||
// appCompatButton.SetTextColor(button.Color.ToNative());
|
||||
}
|
||||
|
||||
public static void UpdateText(this UIButton nativeButton, IButton button) => nativeButton.SetText(button.Text);
|
||||
}
|
||||
}
|
|
@ -64,8 +64,9 @@ namespace Xamarin.Platform
|
|||
public virtual IReadOnlyList<string> UpdateKeys => updateKeys ?? PopulateKeys(ref updateKeys);
|
||||
}
|
||||
|
||||
public class PropertyMapper<TVirtualView> : PropertyMapper, IEnumerable
|
||||
public class PropertyMapper<TVirtualView, TViewHandler> : PropertyMapper, IEnumerable
|
||||
where TVirtualView : IFrameworkElement
|
||||
where TViewHandler : IViewHandler
|
||||
{
|
||||
private PropertyMapper chained;
|
||||
public PropertyMapper Chained
|
||||
|
@ -85,7 +86,7 @@ namespace Xamarin.Platform
|
|||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public Action<IViewHandler, TVirtualView> this[string key]
|
||||
public Action<TViewHandler, TVirtualView> this[string key]
|
||||
{
|
||||
set => Add(key, value, true);
|
||||
}
|
||||
|
@ -99,10 +100,10 @@ namespace Xamarin.Platform
|
|||
Chained = chained;
|
||||
}
|
||||
|
||||
ActionMapper<TVirtualView> actions;
|
||||
public ActionMapper<TVirtualView> Actions
|
||||
ActionMapper<TVirtualView, TViewHandler> actions;
|
||||
public ActionMapper<TVirtualView, TViewHandler> Actions
|
||||
{
|
||||
get => actions ??= new ActionMapper<TVirtualView>(this);
|
||||
get => actions ??= new ActionMapper<TVirtualView, TViewHandler>(this);
|
||||
}
|
||||
|
||||
protected override void ClearKeyCache()
|
||||
|
@ -121,17 +122,27 @@ namespace Xamarin.Platform
|
|||
return Chained?.Get(key) ?? (null, false);
|
||||
}
|
||||
|
||||
public void Add(string key, Action<IViewHandler, TVirtualView> action)
|
||||
public void Add(string key, Action<TViewHandler, TVirtualView> action)
|
||||
=> this[key] = action;
|
||||
|
||||
public void Add(string key, Action<IViewHandler, TVirtualView> action, bool ignoreOnStartup)
|
||||
=> _mapper[key] = ((r, v) => action?.Invoke(r, (TVirtualView)v), ignoreOnStartup);
|
||||
|
||||
|
||||
|
||||
public void Add(string key, Action<TViewHandler, TVirtualView> action, bool ignoreOnStartup)
|
||||
=> _mapper[key] = ((r, v) => action?.Invoke((TViewHandler)r, (TVirtualView)v), ignoreOnStartup);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => _mapper.GetEnumerator();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public class PropertyMapper<TVirtualView> : PropertyMapper<TVirtualView, IViewHandler>
|
||||
where TVirtualView : IFrameworkElement
|
||||
{
|
||||
public PropertyMapper()
|
||||
{
|
||||
}
|
||||
|
||||
public PropertyMapper(PropertyMapper chained) : base(chained)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,5 +130,28 @@ namespace Xamarin.Platform.Handlers.Tests
|
|||
Assert.False(mapperActionWasCalled);
|
||||
Assert.True(wasMapper2Called);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void GenericMappersWorks()
|
||||
{
|
||||
bool wasMapper1Called = false;
|
||||
bool wasMapper2Called = false;
|
||||
var mapper1 = new PropertyMapper<IView, IViewHandler>
|
||||
{
|
||||
[nameof(IView.BackgroundColor)] = (r, v) => wasMapper1Called = true
|
||||
};
|
||||
|
||||
var mapper2 = new PropertyMapper<IButton, ButtonHandler>(mapper1)
|
||||
{
|
||||
[nameof(IButton.Color)] = (r, v) => wasMapper2Called = true
|
||||
};
|
||||
|
||||
mapper2.UpdateProperties(null, new Button());
|
||||
|
||||
Assert.True(wasMapper1Called);
|
||||
Assert.True(wasMapper2Called);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче