未验证 提交 3ea1c981 编写于 作者: A Andres Pineda 提交者: GitHub

Merge pull request #12487 from ajpinedam/ajpm/fix.commandbar.appbaricon

fix(droid): CommandBar AppBarIcon binding issues
......@@ -1266,6 +1266,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\CommandBar\CommandBar_Native_With_AppBarButton_Binding.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\IconSourceTests\IconSourceElementTests.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
......@@ -2905,7 +2909,7 @@
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ContentControlTestsControl\ContentControl_ComboBoxSetNull.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ContentControlTestsControl\ContentControl_FindName.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
......@@ -5693,6 +5697,9 @@
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\BorderTests\BorderWithNullBrushAndNonZeroThickness.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\BorderTests\PanelWithNullBrushAndNonZeroThickness.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\CommandBar\CommandBar_Native_With_AppBarButton_Binding.xaml.cs">
<DependentUpon>CommandBar_Native_With_AppBarButton_Binding.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ImageTests\ImageSourceWriteableBitmapInvalidate_Stretch.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\IconSourceTests\IconSourceElementTests.xaml.cs">
<DependentUpon>IconSourceElementTests.xaml</DependentUpon>
......@@ -8923,6 +8930,7 @@
<Content Include="$(MSBuildThisFileDirectory)Assets\cart.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\check.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\CheckBox.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\closeIcon.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\colored-ellipse.jpg" />
<Content Include="$(MSBuildThisFileDirectory)Assets\ColorPicker.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\colors300.png" />
......@@ -8934,6 +8942,7 @@
<Content Include="$(MSBuildThisFileDirectory)Assets\Diagnostics\exclamation.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\Diagnostics\movie_type_dbox.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\DropdownButton.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\filter.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\FlipView.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\Fonts\Even Badder Mofo.ttf" />
<Content Include="$(MSBuildThisFileDirectory)Assets\Fonts\FamilyGuy-4grW.ttf" />
......@@ -9088,4 +9097,4 @@
<Content Include="$(MSBuildThisFileDirectory)Assets\libre-camera-panorama.svg" />
</ItemGroup>
<Import Project="ItemExclusions.props" />
</Project>
</Project>
\ No newline at end of file
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Uno.UI.Samples.UITests.Helpers;
using Windows.UI.Core;
......@@ -12,12 +13,15 @@ namespace Uno.UI.Samples.Presentation.SamplePages
private string _dynamicTitle;
private string _dynamicSubTitle1;
private string _dynamicSubTitle2;
private bool _isChecked;
public CommandBarViewModel(CoreDispatcher dispatcher) : base(dispatcher)
{
ToggleChecked = GetOrCreateCommand(() => IsChecked = !IsChecked);
StartData();
}
public ICommand ToggleChecked { get; }
private async void StartData()
{
......@@ -59,5 +63,15 @@ namespace Uno.UI.Samples.Presentation.SamplePages
_dynamicSubTitle2 = value; RaisePropertyChanged();
}
}
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
RaisePropertyChanged();
}
}
}
}
<Page
x:Class="UITests.Windows_UI_Xaml_Controls.CommandBar.CommandBar_Native_With_AppBarButton_Binding"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.Windows_UI_Xaml_Controls.CommandBar"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:xamarin="http://nventive.com/xamarin"
xmlns:ios="http://nventive.com/ios"
xmlns:android="http://nventive.com/android"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d xamarin ios android"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<Style x:Name="NativeCommandbarStyle"
TargetType="CommandBar"
xamarin:BasedOn="{StaticResource NativeDefaultCommandBar}">
<Setter Property="Background"
Value="Blue" />
<Setter Property="Foreground"
Value="White" />
</Style>
<local:FromNullableBoolToCustomValueConverter x:Key="IsCheckedToIcon"
TrueValue="ms-appx:///Assets/closeIcon.png"
NullOrFalseValue="ms-appx:///Assets/filter.png" />
</Page.Resources>
<StackPanel Background="White">
<xamarin:Grid>
<CommandBar Content="CommandBar with DataContext Set"
Style="{StaticResource NativeCommandbarStyle}"
Grid.Row="0">
<CommandBar.PrimaryCommands>
<AppBarButton Command="{Binding [ToggleChecked]}"
Label="Order"
Foreground="White">
<AppBarButton.Icon>
<BitmapIcon ShowAsMonochrome="True"
UriSource="{Binding [IsChecked], Converter={StaticResource IsCheckedToIcon}}" />
</AppBarButton.Icon>
</AppBarButton>
</CommandBar.PrimaryCommands>
</CommandBar>
</xamarin:Grid>
</StackPanel>
</Page>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Uno.UI.Samples.Controls;
using Uno.UI.Samples.Presentation.SamplePages;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace UITests.Windows_UI_Xaml_Controls.CommandBar
{
[SampleControlInfo("CommandBar", "Native_AppBarButton_Binding", typeof(CommandBarViewModel), isManualTest: true)]
public sealed partial class CommandBar_Native_With_AppBarButton_Binding : Page
{
public CommandBar_Native_With_AppBarButton_Binding()
{
this.InitializeComponent();
}
}
public class FromNullableBoolToCustomValueConverter : IValueConverter
{
public object NullOrFalseValue { get; set; }
public object TrueValue { get; set; }
public object Convert(object value, Type targetType, object parameter, string language)
{
if (parameter != null)
{
throw new ArgumentException($"This converter does not use any parameters. You should remove \"{parameter}\" passed as parameter.");
}
if (value != null && !(value is bool))
{
throw new ArgumentException($"Value must either be null or of type bool. Got {value} ({value.GetType().FullName})");
}
if (value == null || !System.Convert.ToBoolean(value, CultureInfo.InvariantCulture))
{
return NullOrFalseValue;
}
else
{
return TrueValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
if (parameter != null)
{
throw new ArgumentException($"This converter does not use any parameters. You should remove \"{parameter}\" passed as parameter.");
}
if (object.Equals(this.TrueValue, this.NullOrFalseValue))
{
throw new InvalidOperationException("Cannot convert back if both custom values are the same");
}
return this.TrueValue != null ?
value.Equals(TrueValue) :
!value.Equals(this.NullOrFalseValue);
}
}
}
......@@ -11,11 +11,22 @@
<Grid>
<CommandBar Content="Page with AppBarButton">
<CommandBar.PrimaryCommands>
<AppBarButton Visibility="{Binding ButtonVisibility, FallbackValue=Collapsed}">
<AppBarButton Visibility="{Binding ButtonVisibility, FallbackValue=Collapsed}"
x:Name="innerBarButton"
x:FieldModifier="public">
<TextBlock x:Name="innerTextBlock"
x:FieldModifier="public"
Text="{Binding ButtonText}" />
</AppBarButton>
<AppBarButton Label="Order"
Foreground="White">
<AppBarButton.Icon>
<BitmapIcon ShowAsMonochrome="True"
x:Name="innerIcon"
x:FieldModifier="public"
UriSource="{Binding CommandBarIcon}" />
</AppBarButton.Icon>
</AppBarButton>
</CommandBar.PrimaryCommands>
</CommandBar>
</Grid>
......
......@@ -33,17 +33,47 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls
page.DataContext = new MyContext();
await WindowHelper.WaitForIdle();
var tb = page.innerTextBlock;
var icon = page.innerIcon;
Assert.IsNotNull(tb);
Assert.IsNotNull(icon);
Assert.AreEqual("Archaeopteryx", tb.Text);
Assert.IsTrue(tb.ActualWidth > 0);
Assert.IsTrue(tb.ActualHeight > 0);
}
}
[TestMethod]
#if __MACOS__
[Ignore("Currently fails on macOS, part of #9282 epic")]
#endif
public async Task Check_Binding_No_DataContext()
{
using (StyleHelper.UseNativeFrameNavigation())
{
var frame = new Frame();
WindowHelper.WindowContent = frame;
await WindowHelper.WaitForIdle();
frame.Navigate(typeof(Page_With_AppBarButton_Visibility_Bound));
await WindowHelper.WaitForIdle();
var page = frame.Content as Page_With_AppBarButton_Visibility_Bound;
page.DataContext = null;
Assert.IsNotNull(page);
await WindowHelper.WaitForIdle();
var tb = page.innerTextBlock;
var icon = page.innerIcon;
var barButton1 = page.innerBarButton;
Assert.IsNotNull(tb);
Assert.IsNotNull(icon);
Assert.IsNotNull(barButton1);
Assert.AreEqual(Visibility.Collapsed, barButton1.Visibility);
}
}
private class MyContext
{
public Visibility ButtonVisibility => Visibility.Visible;
public string ButtonText => "Archaeopteryx";
public string CommandBarIcon => "ms-appx:///Assets/linux.png";
}
}
}
#if __ANDROID__
using AndroidX.Core.Graphics.Drawable;
using AndroidX.Core.Graphics.Drawable;
using Android.Views;
using System;
using System.Collections.Generic;
......@@ -208,4 +207,3 @@ namespace Uno.UI.Controls
}
}
}
#endif
using Android.Graphics.Drawables;
#nullable enable
using Android.Graphics.Drawables;
using System;
using System.ComponentModel;
using Windows.UI.Xaml.Media;
......@@ -14,7 +15,7 @@ namespace Uno.UI
/// </summary>
/// <param name="uri">URI</param>
/// <returns>Drawable</returns>
public static Drawable FromUri(Uri uri) =>
public static Drawable? FromUri(Uri uri) =>
Uno.Helpers.DrawableHelper.FromUri(uri);
}
}
......@@ -482,7 +482,7 @@ namespace Windows.UI.Xaml.Media
/// Now available outside in Uno library with <see cref="DrawableHelper"/>.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static Type Drawables
public static Type? Drawables
{
get => Uno.Helpers.DrawableHelper.Drawables;
set => Uno.Helpers.DrawableHelper.Drawables = value;
......
#if __ANDROID__
#nullable enable
using Android.Graphics.Drawables;
using AndroidX.Core.Content;
using AndroidX.Core.Graphics.Drawable;
......@@ -14,12 +14,12 @@ namespace Uno.Helpers
{
public static class DrawableHelper
{
private static Dictionary<string, int> _drawablesLookup;
private static Type _drawables;
private static Dictionary<string, int>? _drawablesLookup;
private static Type? _drawables;
private static Func<string, int> _resolver;
private static Func<string, int>? _resolver;
public static Type Drawables
public static Type? Drawables
{
get => _drawables;
set
......@@ -84,9 +84,14 @@ namespace Uno.Helpers
/// Finds a Drawable by URI
/// </summary>
/// <param name="uri">Uri</param>
/// <returns>Drawable</returns>
public static Drawable FromUri(Uri uri)
/// <returns><seealso cref="Drawable"/> for the URI provided or null otherwise</returns>
public static Drawable? FromUri(Uri uri)
{
if (uri?.PathAndQuery is null)
{
return null;
}
var id = FindResourceIdFromPath(uri.PathAndQuery.TrimStart(new[] { '/' }));
var drawable = id.HasValue
? ContextCompat.GetDrawable(ContextHelper.Current, id.Value)
......@@ -109,13 +114,17 @@ namespace Uno.Helpers
private static void InitializeDrawablesLookup()
{
if (_drawables is null)
{
return;
}
_drawablesLookup = _drawables
.GetFields(BindingFlags.Static | BindingFlags.Public)
.ToDictionary(
p => p.Name,
p => (int)p.GetValue(null)
p => (p.GetValue(null) as int?) ?? 0
);
}
}
}
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册