Merge main into net9.0 (#24385)
### Description of Change Merge main into net9.0
|
@ -209,6 +209,26 @@ Task("dotnet-samples")
|
||||||
RunMSBuildWithDotNet(projectsToBuild, properties, binlogPrefix: "sample-");
|
RunMSBuildWithDotNet(projectsToBuild, properties, binlogPrefix: "sample-");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Builds the host app for the UI Tests
|
||||||
|
Task("uitests-apphost")
|
||||||
|
.IsDependentOn("dotnet-buildtasks")
|
||||||
|
.Does(() =>
|
||||||
|
{
|
||||||
|
var tempDir = PrepareSeparateBuildContext("samplesTest");
|
||||||
|
|
||||||
|
var properties = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
if(useNuget)
|
||||||
|
{
|
||||||
|
properties = new Dictionary<string, string> {
|
||||||
|
["UseWorkload"] = "true",
|
||||||
|
// ["GenerateAppxPackageOnBuild"] = "true",
|
||||||
|
["RestoreConfigFile"] = tempDir.CombineWithFilePath("NuGet.config").FullPath,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
RunMSBuildWithDotNet("./src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj", properties, binlogPrefix: "uitests-apphost-");
|
||||||
|
});
|
||||||
|
|
||||||
Task("dotnet-legacy-controlgallery")
|
Task("dotnet-legacy-controlgallery")
|
||||||
.IsDependentOn("dotnet-legacy-controlgallery-android")
|
.IsDependentOn("dotnet-legacy-controlgallery-android")
|
||||||
.IsDependentOn("dotnet-legacy-controlgallery-ios");
|
.IsDependentOn("dotnet-legacy-controlgallery-ios");
|
||||||
|
|
|
@ -49,7 +49,7 @@ steps:
|
||||||
- pwsh: echo "##vso[task.prependpath]$(DotNet.Dir)"
|
- pwsh: echo "##vso[task.prependpath]$(DotNet.Dir)"
|
||||||
displayName: 'Add .NET to PATH'
|
displayName: 'Add .NET to PATH'
|
||||||
|
|
||||||
- pwsh: ./build.ps1 --target=dotnet-samples --configuration="${{ parameters.configuration }}" --${{ parameters.platform }} --verbosity=diagnostic --usenuget=false --runtimevariant="${{ parameters.runtimeVariant }}"
|
- pwsh: ./build.ps1 --target=uitests-apphost --configuration="${{ parameters.configuration }}" --${{ parameters.platform }} --verbosity=diagnostic --usenuget=false --runtimevariant="${{ parameters.runtimeVariant }}"
|
||||||
displayName: 'Build the samples'
|
displayName: 'Build the samples'
|
||||||
|
|
||||||
- bash: |
|
- bash: |
|
||||||
|
|
|
@ -998,23 +998,35 @@ namespace Microsoft.Maui.Controls.Build.Tasks
|
||||||
// IL_008e: newobj instance void class [mscorlib]System.Tuple`2<class [mscorlib]System.Func`2<class ViewModel, object>, string>::'.ctor'(!0, !1)
|
// IL_008e: newobj instance void class [mscorlib]System.Tuple`2<class [mscorlib]System.Func`2<class ViewModel, object>, string>::'.ctor'(!0, !1)
|
||||||
// IL_0093: stelem.ref
|
// IL_0093: stelem.ref
|
||||||
|
|
||||||
yield return Create(Ldc_I4, properties.Count);
|
var handlers = new List<(MethodDefinition PartGetter, string PropertyName)>();
|
||||||
yield return Create(Newarr, tupleRef);
|
for (int i = 0; i < properties.Count; i++)
|
||||||
|
|
||||||
for (var i = 0; i < properties.Count; i++)
|
|
||||||
{
|
{
|
||||||
if (properties[i].property == null)
|
if (properties[i].property == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
var partGetter = partGetters[i];
|
||||||
|
var propertyName = properties[i].Item1.Name;
|
||||||
|
|
||||||
|
handlers.Add((partGetter, propertyName));
|
||||||
|
|
||||||
|
// for indexers add also a handler for the specific index
|
||||||
|
if (properties[i].Item3 is not null)
|
||||||
|
{
|
||||||
|
handlers.Add((partGetter, $"{propertyName}[{properties[i].Item3}]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return Create(Ldc_I4, handlers.Count);
|
||||||
|
yield return Create(Newarr, tupleRef);
|
||||||
|
|
||||||
|
for (var i = 0; i < handlers.Count; i++)
|
||||||
|
{
|
||||||
yield return Create(Dup);
|
yield return Create(Dup);
|
||||||
yield return Create(Ldc_I4, i);
|
yield return Create(Ldc_I4, i);
|
||||||
yield return Create(Ldnull);
|
yield return Create(Ldnull);
|
||||||
yield return Create(Ldftn, partGetters[i]);
|
yield return Create(Ldftn, handlers[i].PartGetter);
|
||||||
yield return Create(Newobj, module.ImportReference(funcCtor));
|
yield return Create(Newobj, module.ImportReference(funcCtor));
|
||||||
if (properties[i].Item3 == null) //no indexer
|
yield return Create(Ldstr, handlers[i].PropertyName);
|
||||||
yield return Create(Ldstr, properties[i].Item1.Name);
|
|
||||||
else
|
|
||||||
yield return Create(Ldstr, $"{properties[i].Item1.Name}[{properties[i].Item3}]");
|
|
||||||
|
|
||||||
yield return Create(Newobj, module.ImportReference(tupleCtor));
|
yield return Create(Newobj, module.ImportReference(tupleCtor));
|
||||||
yield return Create(Stelem_Ref);
|
yield return Create(Stelem_Ref);
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,29 +428,34 @@ namespace Microsoft.Maui.Controls.Handlers.Items
|
||||||
var item = args.Item;
|
var item = args.Item;
|
||||||
if (args.Mode == ScrollToMode.Position)
|
if (args.Mode == ScrollToMode.Position)
|
||||||
{
|
{
|
||||||
item = FindBoundItem(args);
|
// Do not use `IGroupableItemsViewSource` since `UngroupedItemsSource` also implements that interface
|
||||||
|
if (ItemsViewAdapter.ItemsSource is UngroupedItemsSource)
|
||||||
|
{
|
||||||
|
return args.Index;
|
||||||
|
}
|
||||||
|
else if (ItemsViewAdapter.ItemsSource is IGroupableItemsViewSource groupItemSource)
|
||||||
|
{
|
||||||
|
item = FindBoundItemInGroup(args, groupItemSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ItemsViewAdapter.GetPositionForItem(item);
|
return ItemsViewAdapter.GetPositionForItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private object FindBoundItem(ScrollToRequestEventArgs args)
|
private static object FindBoundItemInGroup(ScrollToRequestEventArgs args, IGroupableItemsViewSource groupItemSource)
|
||||||
{
|
{
|
||||||
if (args.Index >= ItemsViewAdapter.ItemsSource.Count)
|
if (args.GroupIndex >= 0 &&
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ItemsViewAdapter.ItemsSource is IGroupableItemsViewSource groupItemSource &&
|
|
||||||
args.GroupIndex >= 0 &&
|
|
||||||
args.GroupIndex < groupItemSource.Count)
|
args.GroupIndex < groupItemSource.Count)
|
||||||
{
|
{
|
||||||
var group = groupItemSource.GetGroupItemsViewSource(args.GroupIndex);
|
var group = groupItemSource.GetGroupItemsViewSource(args.GroupIndex);
|
||||||
|
|
||||||
// NOTE: GetItem calls AdjustIndexRequest, which subtracts 1 if we have a header
|
if (group is not null)
|
||||||
return group.GetItem(args.Index + 1);
|
{
|
||||||
|
// GetItem calls AdjustIndexRequest, which subtracts 1 if we have a header (UngroupedItemsSource does not do this)
|
||||||
|
return group.GetItem(args.Index + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ItemsViewAdapter.ItemsSource.GetItem(args.Index);
|
return groupItemSource.GetItem(args.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void UpdateItemSpacing()
|
protected virtual void UpdateItemSpacing()
|
||||||
|
|
|
@ -79,6 +79,7 @@ namespace Microsoft.Maui.Controls.Platform
|
||||||
Foreground = textColor?.ToPlatform(),
|
Foreground = textColor?.ToPlatform(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
run.Foreground = textColor?.ToPlatform();
|
||||||
textBlock.TextHighlighters.Add(textHighlighter);
|
textBlock.TextHighlighters.Add(textHighlighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,65 @@ namespace Microsoft.Maui.DeviceTests
|
||||||
#if IOS || MACCATALYST || WINDOWS
|
#if IOS || MACCATALYST || WINDOWS
|
||||||
Skip = "Fails: https://github.com/dotnet/maui/issues/17664"
|
Skip = "Fails: https://github.com/dotnet/maui/issues/17664"
|
||||||
#endif
|
#endif
|
||||||
|
)]
|
||||||
|
public async Task CollectionScrollToUngroupedWorks()
|
||||||
|
{
|
||||||
|
SetupBuilder();
|
||||||
|
|
||||||
|
var dataList = new List<TestData>();
|
||||||
|
string letters = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
for (int i = 0; i < letters.Length; i++)
|
||||||
|
{
|
||||||
|
dataList.Add(new TestData
|
||||||
|
{
|
||||||
|
Name = $"{letters[i]}"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var collectionView = new CollectionView
|
||||||
|
{
|
||||||
|
IsGrouped = false,
|
||||||
|
ItemsSource = dataList,
|
||||||
|
ItemTemplate = new DataTemplate(() =>
|
||||||
|
{
|
||||||
|
var name = new Label()
|
||||||
|
{
|
||||||
|
TextColor = Colors.Grey,
|
||||||
|
HeightRequest = 64
|
||||||
|
};
|
||||||
|
name.SetBinding(Label.TextProperty, "Name");
|
||||||
|
return name;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
await CreateHandlerAndAddToWindow<CollectionViewHandler>(collectionView, async handler =>
|
||||||
|
{
|
||||||
|
collectionView.ScrollTo(index: 24, animate: false); // Item "x"
|
||||||
|
|
||||||
|
int retryCount = 3;
|
||||||
|
bool foundItem = false;
|
||||||
|
while (retryCount > 0 && !foundItem)
|
||||||
|
{
|
||||||
|
retryCount--;
|
||||||
|
await Task.Delay(500);
|
||||||
|
for (int i = 0; i < collectionView.LogicalChildrenInternal.Count; i++)
|
||||||
|
{
|
||||||
|
var item = collectionView.LogicalChildrenInternal[i];
|
||||||
|
if (item is Label label && label.Text.Equals("x", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foundItem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.True(foundItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact(
|
||||||
|
#if IOS || MACCATALYST
|
||||||
|
Skip = "Fails on iOS/macOS: https://github.com/dotnet/maui/issues/17664"
|
||||||
|
#endif
|
||||||
)]
|
)]
|
||||||
public async Task CollectionScrollToGroupWorks()
|
public async Task CollectionScrollToGroupWorks()
|
||||||
{
|
{
|
||||||
|
|
Двоичные данные
src/Controls/tests/TestCases.Android.Tests/snapshots/android/LabelHyperlinkUnderlineColor.png
Normal file
После Ширина: | Высота: | Размер: 8.9 KiB |
Двоичные данные
src/Controls/tests/TestCases.Android.Tests/snapshots/android/SettingDatePickerBackgroundFromHandler.png
Normal file
После Ширина: | Высота: | Размер: 40 KiB |
Двоичные данные
src/Controls/tests/TestCases.Android.Tests/snapshots/android/SettingEditorBackgroundFromHandler.png
Normal file
После Ширина: | Высота: | Размер: 15 KiB |
Двоичные данные
src/Controls/tests/TestCases.Android.Tests/snapshots/android/SettingEntryBackgroundFromHandler.png
Normal file
После Ширина: | Высота: | Размер: 16 KiB |
Двоичные данные
src/Controls/tests/TestCases.Android.Tests/snapshots/android/SettingTimePickerBackgroundFromHandler.png
Normal file
После Ширина: | Высота: | Размер: 40 KiB |
|
@ -0,0 +1,24 @@
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
|
||||||
|
namespace Maui.Controls.Sample.Issues
|
||||||
|
{
|
||||||
|
[Issue(IssueTracker.Github, 10645, "Image is not centered in AspectFill mode", PlatformAffected.UWP)]
|
||||||
|
public class Issue10645 : TestContentPage
|
||||||
|
{
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
Content =
|
||||||
|
new Grid()
|
||||||
|
{
|
||||||
|
new Image()
|
||||||
|
{
|
||||||
|
AutomationId = "AspectFillImage",
|
||||||
|
Aspect = Microsoft.Maui.Aspect.AspectFill,
|
||||||
|
WidthRequest = 100,
|
||||||
|
HeightRequest = 200,
|
||||||
|
Source = "dotnet_bot.png",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Maui.Controls.Sample.Issues.Issue18720"
|
||||||
|
xmlns:controls="clr-namespace:Maui.Controls.Sample.Issues">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="HeightRequest" Value="36" />
|
||||||
|
<Setter Property="FontSize" Value="9" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ContentPage.Resources>
|
||||||
|
<VerticalStackLayout
|
||||||
|
Padding="30,0"
|
||||||
|
Spacing="25">
|
||||||
|
<VerticalStackLayout
|
||||||
|
x:Name="TestLayout">
|
||||||
|
<Label
|
||||||
|
Text="BackgroundColor" />
|
||||||
|
<Entry
|
||||||
|
x:Name="BackgroundColorEntry"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundColorButton"
|
||||||
|
Text="Update Background Color"
|
||||||
|
Clicked="OnUpdateBackgroundColorButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundColorButton"
|
||||||
|
Text="Clear Background Color"
|
||||||
|
Clicked="OnClearBackgroundColorButtonClicked"/>
|
||||||
|
<Label
|
||||||
|
Text="Background" />
|
||||||
|
<Entry
|
||||||
|
x:Name="BackgroundEntry"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundButton"
|
||||||
|
Text="Update Background"
|
||||||
|
Clicked="OnUpdateBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundButton"
|
||||||
|
Text="Clear Background"
|
||||||
|
Clicked="OnClearBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="TestButton"
|
||||||
|
AutomationId="TestButton"
|
||||||
|
Text="Test"
|
||||||
|
Margin="0, 12"
|
||||||
|
Clicked="OnTestButtonClicked"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
<Label
|
||||||
|
Text="Custom Entry (Null Android Background)" />
|
||||||
|
<controls:Issue18720Entry1
|
||||||
|
AutomationId="CustomEntry1"/>
|
||||||
|
<Label
|
||||||
|
Text="Custom Entry (Custom Android Drawable)" />
|
||||||
|
<controls:Issue18720Entry2
|
||||||
|
AutomationId="CustomEntry2"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,117 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Xaml;
|
||||||
|
using Microsoft.Maui.Graphics;
|
||||||
|
using Microsoft.Maui.Hosting;
|
||||||
|
|
||||||
|
namespace Maui.Controls.Sample.Issues
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
[Issue(IssueTracker.Github, 18720, "Setting the background property of AppCompatEditText (Entry) in a handler mapping does not work", PlatformAffected.Android)]
|
||||||
|
public partial class Issue18720 : ContentPage
|
||||||
|
{
|
||||||
|
public Issue18720()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
UpdateEntryBackgroundColor();
|
||||||
|
UpdateEntryBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundColorButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateEntryBackgroundColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundColorButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundColorEntry.BackgroundColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateEntryBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundEntry.Background = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTestButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
TestLayout.IsVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateEntryBackgroundColor()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color backgroundColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
BackgroundColorEntry.BackgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateEntryBackground()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color startColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
Color endColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
|
||||||
|
BackgroundEntry.Background = new LinearGradientBrush
|
||||||
|
{
|
||||||
|
EndPoint = new Point(1, 0),
|
||||||
|
GradientStops = new GradientStopCollection
|
||||||
|
{
|
||||||
|
new GradientStop { Color = startColor },
|
||||||
|
new GradientStop { Color = endColor, Offset = 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720Entry1 : Entry
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720Entry2 : Entry
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Issue18720Extensions
|
||||||
|
{
|
||||||
|
public static MauiAppBuilder Issue18720AddMappers(this MauiAppBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureMauiHandlers(handlers =>
|
||||||
|
{
|
||||||
|
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(nameof(Issue18720Entry1), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720Entry1)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
handler.PlatformView.Background = null;
|
||||||
|
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Pink);
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.WhiteSmoke);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(nameof(Issue18720Entry2), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720Entry2)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
Android.Graphics.Drawables.GradientDrawable gd = new Android.Graphics.Drawables.GradientDrawable();
|
||||||
|
gd.SetCornerRadius(10);
|
||||||
|
gd.SetStroke(2, Android.Graphics.Color.Violet);
|
||||||
|
handler.PlatformView.Background = gd;
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.DeepPink);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Maui.Controls.Sample.Issues.Issue18720DatePicker"
|
||||||
|
xmlns:controls="clr-namespace:Maui.Controls.Sample.Issues">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="HeightRequest" Value="36" />
|
||||||
|
<Setter Property="FontSize" Value="9" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ContentPage.Resources>
|
||||||
|
<VerticalStackLayout
|
||||||
|
Padding="30,0"
|
||||||
|
Spacing="25">
|
||||||
|
<VerticalStackLayout
|
||||||
|
x:Name="TestLayout">
|
||||||
|
<Label
|
||||||
|
Text="BackgroundColor" />
|
||||||
|
<DatePicker
|
||||||
|
x:Name="BackgroundColorDatePicker"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundColorButton"
|
||||||
|
Text="Update Background Color"
|
||||||
|
Clicked="OnUpdateBackgroundColorButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundColorButton"
|
||||||
|
Text="Clear Background Color"
|
||||||
|
Clicked="OnClearBackgroundColorButtonClicked"/>
|
||||||
|
<Label
|
||||||
|
Text="Background" />
|
||||||
|
<DatePicker
|
||||||
|
x:Name="BackgroundDatePicker"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundButton"
|
||||||
|
Text="Update Background"
|
||||||
|
Clicked="OnUpdateBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundButton"
|
||||||
|
Text="Clear Background"
|
||||||
|
Clicked="OnClearBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="TestButton"
|
||||||
|
AutomationId="TestButton"
|
||||||
|
Text="Test"
|
||||||
|
Margin="0, 12"
|
||||||
|
Clicked="OnTestButtonClicked"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
<Label
|
||||||
|
Text="Custom DatePicker (Null Android Background)" />
|
||||||
|
<controls:Issue18720DatePicker1
|
||||||
|
AutomationId="CustomDatePicker1"/>
|
||||||
|
<Label
|
||||||
|
Text="Custom DatePicker (Custom Android Drawable)" />
|
||||||
|
<controls:Issue18720DatePicker2
|
||||||
|
AutomationId="CustomDatePicker2"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,117 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Xaml;
|
||||||
|
using Microsoft.Maui.Graphics;
|
||||||
|
using Microsoft.Maui.Hosting;
|
||||||
|
|
||||||
|
namespace Maui.Controls.Sample.Issues
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
[Issue(IssueTracker.ManualTest, "18720 DatePicker", "Setting the background property of AppCompatEditText (DatePicker) in a handler mapping does not work", PlatformAffected.Android)]
|
||||||
|
public partial class Issue18720DatePicker : ContentPage
|
||||||
|
{
|
||||||
|
public Issue18720DatePicker()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
UpdateDatePickerBackgroundColor();
|
||||||
|
UpdateDatePickerBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundColorButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateDatePickerBackgroundColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundColorButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundColorDatePicker.BackgroundColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateDatePickerBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundDatePicker.Background = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTestButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
TestLayout.IsVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDatePickerBackgroundColor()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color backgroundColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
BackgroundColorDatePicker.BackgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDatePickerBackground()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color startColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
Color endColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
|
||||||
|
BackgroundDatePicker.Background = new LinearGradientBrush
|
||||||
|
{
|
||||||
|
EndPoint = new Point(1, 0),
|
||||||
|
GradientStops = new GradientStopCollection
|
||||||
|
{
|
||||||
|
new GradientStop { Color = startColor },
|
||||||
|
new GradientStop { Color = endColor, Offset = 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720DatePicker1 : DatePicker
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720DatePicker2 : DatePicker
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Issue18720DatePickerExtensions
|
||||||
|
{
|
||||||
|
public static MauiAppBuilder Issue18720DatePickerAddMappers(this MauiAppBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureMauiHandlers(handlers =>
|
||||||
|
{
|
||||||
|
Microsoft.Maui.Handlers.DatePickerHandler.Mapper.AppendToMapping(nameof(Issue18720DatePicker1), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720DatePicker1)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
handler.PlatformView.Background = null;
|
||||||
|
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Pink);
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.WhiteSmoke);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Microsoft.Maui.Handlers.DatePickerHandler.Mapper.AppendToMapping(nameof(Issue18720DatePicker2), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720DatePicker2)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
Android.Graphics.Drawables.GradientDrawable gd = new Android.Graphics.Drawables.GradientDrawable();
|
||||||
|
gd.SetCornerRadius(10);
|
||||||
|
gd.SetStroke(2, Android.Graphics.Color.Violet);
|
||||||
|
handler.PlatformView.Background = gd;
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.DeepPink);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Maui.Controls.Sample.Issues.Issue18720Editor"
|
||||||
|
xmlns:controls="clr-namespace:Maui.Controls.Sample.Issues">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="HeightRequest" Value="36" />
|
||||||
|
<Setter Property="FontSize" Value="9" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ContentPage.Resources>
|
||||||
|
<VerticalStackLayout
|
||||||
|
Padding="30,0"
|
||||||
|
Spacing="25">
|
||||||
|
<VerticalStackLayout
|
||||||
|
x:Name="TestLayout">
|
||||||
|
<Label
|
||||||
|
Text="BackgroundColor" />
|
||||||
|
<Editor
|
||||||
|
x:Name="BackgroundColorEditor"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundColorButton"
|
||||||
|
Text="Update Background Color"
|
||||||
|
Clicked="OnUpdateBackgroundColorButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundColorButton"
|
||||||
|
Text="Clear Background Color"
|
||||||
|
Clicked="OnClearBackgroundColorButtonClicked"/>
|
||||||
|
<Label
|
||||||
|
Text="Background" />
|
||||||
|
<Editor
|
||||||
|
x:Name="BackgroundEditor"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundButton"
|
||||||
|
Text="Update Background"
|
||||||
|
Clicked="OnUpdateBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundButton"
|
||||||
|
Text="Clear Background"
|
||||||
|
Clicked="OnClearBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="TestButton"
|
||||||
|
AutomationId="TestButton"
|
||||||
|
Text="Test"
|
||||||
|
Margin="0, 12"
|
||||||
|
Clicked="OnTestButtonClicked"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
<Label
|
||||||
|
Text="Custom Editor (Null Android Background)" />
|
||||||
|
<controls:Issue18720Editor1
|
||||||
|
AutomationId="CustomEditor1"/>
|
||||||
|
<Label
|
||||||
|
Text="Custom Editor (Custom Android Drawable)" />
|
||||||
|
<controls:Issue18720Editor2
|
||||||
|
AutomationId="CustomEditor2"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,117 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Xaml;
|
||||||
|
using Microsoft.Maui.Graphics;
|
||||||
|
using Microsoft.Maui.Hosting;
|
||||||
|
|
||||||
|
namespace Maui.Controls.Sample.Issues
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
[Issue(IssueTracker.Github, "18720 Editor", "Setting the background property of AppCompatEditText (Editor) in a handler mapping does not work", PlatformAffected.Android)]
|
||||||
|
public partial class Issue18720Editor : ContentPage
|
||||||
|
{
|
||||||
|
public Issue18720Editor()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
UpdateEditorBackgroundColor();
|
||||||
|
UpdateEditorBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundColorButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateEditorBackgroundColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundColorButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundColorEditor.BackgroundColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateEditorBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundButtonClicked(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundEditor.Background = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTestButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
TestLayout.IsVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateEditorBackgroundColor()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color backgroundColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
BackgroundColorEditor.BackgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateEditorBackground()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color startColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
Color endColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
|
||||||
|
BackgroundEditor.Background = new LinearGradientBrush
|
||||||
|
{
|
||||||
|
EndPoint = new Point(1, 0),
|
||||||
|
GradientStops = new GradientStopCollection
|
||||||
|
{
|
||||||
|
new GradientStop { Color = startColor },
|
||||||
|
new GradientStop { Color = endColor, Offset = 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720Editor1 : Editor
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720Editor2 : Editor
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Issue18720EditorExtensions
|
||||||
|
{
|
||||||
|
public static MauiAppBuilder Issue18720EditorAddMappers(this MauiAppBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureMauiHandlers(handlers =>
|
||||||
|
{
|
||||||
|
Microsoft.Maui.Handlers.EditorHandler.Mapper.AppendToMapping(nameof(Issue18720Editor1), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720Editor1)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
handler.PlatformView.Background = null;
|
||||||
|
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Pink);
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.WhiteSmoke);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Microsoft.Maui.Handlers.EditorHandler.Mapper.AppendToMapping(nameof(Issue18720Editor2), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720Editor2)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
Android.Graphics.Drawables.GradientDrawable gd = new Android.Graphics.Drawables.GradientDrawable();
|
||||||
|
gd.SetCornerRadius(10);
|
||||||
|
gd.SetStroke(2, Android.Graphics.Color.Violet);
|
||||||
|
handler.PlatformView.Background = gd;
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.DeepPink);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Maui.Controls.Sample.Issues.Issue18720TimePicker"
|
||||||
|
xmlns:controls="clr-namespace:Maui.Controls.Sample.Issues">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="HeightRequest" Value="36" />
|
||||||
|
<Setter Property="FontSize" Value="9" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ContentPage.Resources>
|
||||||
|
<VerticalStackLayout
|
||||||
|
Padding="30,0"
|
||||||
|
Spacing="25">
|
||||||
|
<VerticalStackLayout
|
||||||
|
x:Name="TestLayout">
|
||||||
|
<Label
|
||||||
|
Text="BackgroundColor" />
|
||||||
|
<TimePicker
|
||||||
|
x:Name="BackgroundColorTimePicker"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundColorButton"
|
||||||
|
Text="Update Background Color"
|
||||||
|
Clicked="OnUpdateBackgroundColorButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundColorButton"
|
||||||
|
Text="Clear Background Color"
|
||||||
|
Clicked="OnClearBackgroundColorButtonClicked"/>
|
||||||
|
<Label
|
||||||
|
Text="Background" />
|
||||||
|
<TimePicker
|
||||||
|
x:Name="BackgroundTimePicker"/>
|
||||||
|
<Button
|
||||||
|
x:Name="UpdateBackgroundButton"
|
||||||
|
Text="Update Background"
|
||||||
|
Clicked="OnUpdateBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="ClearBackgroundButton"
|
||||||
|
Text="Clear Background"
|
||||||
|
Clicked="OnClearBackgroundButtonClicked"/>
|
||||||
|
<Button
|
||||||
|
x:Name="TestButton"
|
||||||
|
AutomationId="TestButton"
|
||||||
|
Text="Test"
|
||||||
|
Margin="0, 12"
|
||||||
|
Clicked="OnTestButtonClicked"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
<Label
|
||||||
|
Text="Custom TimePicker (Null Android Background)" />
|
||||||
|
<controls:Issue18720TimePicker1
|
||||||
|
AutomationId="CustomTimePicker1"/>
|
||||||
|
<Label
|
||||||
|
Text="Custom TimePicker (Custom Android Drawable)" />
|
||||||
|
<controls:Issue18720TimePicker2
|
||||||
|
AutomationId="CustomTimePicker2"/>
|
||||||
|
</VerticalStackLayout>
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,117 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Xaml;
|
||||||
|
using Microsoft.Maui.Graphics;
|
||||||
|
using Microsoft.Maui.Hosting;
|
||||||
|
|
||||||
|
namespace Maui.Controls.Sample.Issues
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
[Issue(IssueTracker.ManualTest, "18720 TimePicker", "Setting the background property of AppCompatEditText (TimePicker) in a handler mapping does not work", PlatformAffected.Android)]
|
||||||
|
public partial class Issue18720TimePicker : ContentPage
|
||||||
|
{
|
||||||
|
public Issue18720TimePicker()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
UpdateTimePickerBackgroundColor();
|
||||||
|
UpdateTimePickerBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundColorButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateTimePickerBackgroundColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundColorButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundColorTimePicker.BackgroundColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdateBackgroundButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateTimePickerBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClearBackgroundButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
BackgroundTimePicker.Background = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTestButtonClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
TestLayout.IsVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateTimePickerBackgroundColor()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color backgroundColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
BackgroundColorTimePicker.BackgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateTimePickerBackground()
|
||||||
|
{
|
||||||
|
Random rnd = new Random();
|
||||||
|
Color startColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
Color endColor = Color.FromRgba(rnd.Next(256), rnd.Next(256), rnd.Next(256), 255);
|
||||||
|
|
||||||
|
BackgroundTimePicker.Background = new LinearGradientBrush
|
||||||
|
{
|
||||||
|
EndPoint = new Point(1, 0),
|
||||||
|
GradientStops = new GradientStopCollection
|
||||||
|
{
|
||||||
|
new GradientStop { Color = startColor },
|
||||||
|
new GradientStop { Color = endColor, Offset = 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720TimePicker1 : TimePicker
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Issue18720TimePicker2 : TimePicker
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Issue18720TimePickerExtensions
|
||||||
|
{
|
||||||
|
public static MauiAppBuilder Issue18720TimePickerAddMappers(this MauiAppBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureMauiHandlers(handlers =>
|
||||||
|
{
|
||||||
|
Microsoft.Maui.Handlers.TimePickerHandler.Mapper.AppendToMapping(nameof(Issue18720TimePicker1), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720TimePicker1)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
handler.PlatformView.Background = null;
|
||||||
|
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Pink);
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.WhiteSmoke);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Microsoft.Maui.Handlers.TimePickerHandler.Mapper.AppendToMapping(nameof(Issue18720TimePicker2), (handler, view) =>
|
||||||
|
{
|
||||||
|
if (view is Issue18720TimePicker2)
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
Android.Graphics.Drawables.GradientDrawable gd = new Android.Graphics.Drawables.GradientDrawable();
|
||||||
|
gd.SetCornerRadius(10);
|
||||||
|
gd.SetStroke(2, Android.Graphics.Color.Violet);
|
||||||
|
handler.PlatformView.Background = gd;
|
||||||
|
handler.PlatformView.SetTextColor(Android.Graphics.Color.DeepPink);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Maui.Controls.Sample.Issues.Issue23488">
|
||||||
|
|
||||||
|
<StackLayout HorizontalOptions="Center"
|
||||||
|
VerticalOptions="Center">
|
||||||
|
<Label Text="hyperlink"
|
||||||
|
TextColor="Blue"
|
||||||
|
TextDecorations="Underline" />
|
||||||
|
<Label AutomationId="WaitForLabelControl">
|
||||||
|
<Label.FormattedText>
|
||||||
|
<FormattedString>
|
||||||
|
<Span Text="hyperlink"
|
||||||
|
TextColor="Blue"
|
||||||
|
TextDecorations="Underline" />
|
||||||
|
</FormattedString>
|
||||||
|
</Label.FormattedText>
|
||||||
|
</Label>
|
||||||
|
</StackLayout>
|
||||||
|
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Maui.Controls.Sample.Issues
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
[Issue(IssueTracker.Github, 23488, "Span text-decoration is incorrect whereas the Label behaves properly", PlatformAffected.UWP)]
|
||||||
|
public partial class Issue23488 : ContentPage
|
||||||
|
{
|
||||||
|
public Issue23488()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using Maui.Controls.Sample.Issues;
|
using Maui.Controls.Sample.Issues;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
|
@ -23,7 +23,11 @@ namespace Maui.Controls.Sample
|
||||||
fonts.AddFont("FontAwesome.ttf", "FA");
|
fonts.AddFont("FontAwesome.ttf", "FA");
|
||||||
fonts.AddFont("ionicons.ttf", "Ion");
|
fonts.AddFont("ionicons.ttf", "Ion");
|
||||||
})
|
})
|
||||||
.Issue21109AddMappers();
|
.Issue21109AddMappers()
|
||||||
|
.Issue18720AddMappers()
|
||||||
|
.Issue18720EditorAddMappers()
|
||||||
|
.Issue18720DatePickerAddMappers()
|
||||||
|
.Issue18720TimePickerAddMappers();
|
||||||
|
|
||||||
appBuilder.Services.AddTransient<TransientPage>();
|
appBuilder.Services.AddTransient<TransientPage>();
|
||||||
appBuilder.Services.AddScoped<ScopedPage>();
|
appBuilder.Services.AddScoped<ScopedPage>();
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#if WINDOWS
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UITest.Appium;
|
||||||
|
using UITest.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.TestCases.Tests.Issues
|
||||||
|
{
|
||||||
|
public class Issue10645 : _IssuesUITest
|
||||||
|
{
|
||||||
|
public Issue10645(TestDevice device) : base(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Issue => "Image is not centered in AspectFill mode";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Category(UITestCategories.ActionSheet)]
|
||||||
|
public void Issue10645Test()
|
||||||
|
{
|
||||||
|
App.WaitForElement("AspectFillImage", timeout: TimeSpan.FromSeconds(4));
|
||||||
|
|
||||||
|
VerifyScreenshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
#if ANDROID
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UITest.Appium;
|
||||||
|
using UITest.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.TestCases.Tests.Issues
|
||||||
|
{
|
||||||
|
public class Issue18720 : _IssuesUITest
|
||||||
|
{
|
||||||
|
public Issue18720(TestDevice device) : base(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Issue => "Setting the background property of AppCompatEditText (Entry) in a handler mapping does not work";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Category(UITestCategories.Entry)]
|
||||||
|
public async Task SettingEntryBackgroundFromHandler()
|
||||||
|
{
|
||||||
|
App.WaitForElement("TestButton");
|
||||||
|
App.Tap("TestButton");
|
||||||
|
App.WaitForElement("CustomEntry1");
|
||||||
|
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
VerifyScreenshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
#if ANDROID
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UITest.Appium;
|
||||||
|
using UITest.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.TestCases.Tests.Issues
|
||||||
|
{
|
||||||
|
public class Issue18720DatePicker : _IssuesUITest
|
||||||
|
{
|
||||||
|
public Issue18720DatePicker(TestDevice device) : base(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Issue => "Setting the background property of AppCompatEditText (DatePicker) in a handler mapping does not work";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Category(UITestCategories.DatePicker)]
|
||||||
|
public async Task SettingDatePickerBackgroundFromHandler()
|
||||||
|
{
|
||||||
|
App.WaitForElement("TestButton");
|
||||||
|
App.Tap("TestButton");
|
||||||
|
App.WaitForElement("CustomDatePicker1");
|
||||||
|
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
VerifyScreenshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
#if ANDROID
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UITest.Appium;
|
||||||
|
using UITest.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.TestCases.Tests.Issues
|
||||||
|
{
|
||||||
|
public class Issue18720Editor : _IssuesUITest
|
||||||
|
{
|
||||||
|
public Issue18720Editor(TestDevice device) : base(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Issue => "Setting the background property of AppCompatEditText (Editor) in a handler mapping does not work";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Category(UITestCategories.Editor)]
|
||||||
|
public async Task SettingEditorBackgroundFromHandler()
|
||||||
|
{
|
||||||
|
App.WaitForElement("TestButton");
|
||||||
|
App.Tap("TestButton");
|
||||||
|
App.WaitForElement("CustomEditor1");
|
||||||
|
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
VerifyScreenshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
#if ANDROID
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UITest.Appium;
|
||||||
|
using UITest.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.TestCases.Tests.Issues
|
||||||
|
{
|
||||||
|
public class Issue18720TimePicker : _IssuesUITest
|
||||||
|
{
|
||||||
|
public Issue18720TimePicker(TestDevice device) : base(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Issue => "Setting the background property of AppCompatEditText (TimePicker) in a handler mapping does not work";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Category(UITestCategories.TimePicker)]
|
||||||
|
public async Task SettingTimePickerBackgroundFromHandler()
|
||||||
|
{
|
||||||
|
App.WaitForElement("TestButton");
|
||||||
|
App.Tap("TestButton");
|
||||||
|
App.WaitForElement("CustomTimePicker1");
|
||||||
|
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
VerifyScreenshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
#if !MACCATALYST
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UITest.Appium;
|
||||||
|
using UITest.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.TestCases.Tests.Issues
|
||||||
|
{
|
||||||
|
public class Issue23488 : _IssuesUITest
|
||||||
|
{
|
||||||
|
public Issue23488(TestDevice device): base(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Issue => "Span text-decoration is incorrect whereas the Label behaves properly";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Category(UITestCategories.Label)]
|
||||||
|
public void LabelHyperlinkUnderlineColor()
|
||||||
|
{
|
||||||
|
App.WaitForElement("WaitForLabelControl");
|
||||||
|
VerifyScreenshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
Двоичные данные
src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue10645Test.png
Normal file
После Ширина: | Высота: | Размер: 24 KiB |
Двоичные данные
src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LabelHyperlinkUnderlineColor.png
Normal file
После Ширина: | Высота: | Размер: 3.5 KiB |
Двоичные данные
src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/LabelHyperlinkUnderlineColor.png
Normal file
После Ширина: | Высота: | Размер: 20 KiB |
|
@ -98,6 +98,10 @@ namespace Microsoft.Maui.Controls.Xaml.UnitTests
|
||||||
vm.Model[3] = "TextIndex2";
|
vm.Model[3] = "TextIndex2";
|
||||||
Assert.AreEqual("TextIndex2", layout.label3.Text);
|
Assert.AreEqual("TextIndex2", layout.label3.Text);
|
||||||
|
|
||||||
|
//https://github.com/dotnet/maui/issues/23621
|
||||||
|
vm.Model.SetIndexerValueAndCallOnPropertyChangedWithoutIndex(3, "TextIndex3");
|
||||||
|
Assert.AreEqual("TextIndex3", layout.label3.Text);
|
||||||
|
|
||||||
//testing 2way
|
//testing 2way
|
||||||
Assert.AreEqual("Text2", layout.entry0.Text);
|
Assert.AreEqual("Text2", layout.entry0.Text);
|
||||||
((IElementController)layout.entry0).SetValueFromRenderer(Entry.TextProperty, "Text3");
|
((IElementController)layout.entry0).SetValueFromRenderer(Entry.TextProperty, "Text3");
|
||||||
|
@ -235,6 +239,15 @@ namespace Microsoft.Maui.Controls.Xaml.UnitTests
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetIndexerValueAndCallOnPropertyChangedWithoutIndex(int v, string value)
|
||||||
|
{
|
||||||
|
if (values[v] == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
values[v] = value;
|
||||||
|
OnPropertyChanged("Indexer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockItemViewModel : INotifyPropertyChanged
|
class MockItemViewModel : INotifyPropertyChanged
|
||||||
|
|
|
@ -136,7 +136,12 @@ namespace Microsoft.Maui
|
||||||
var visualElements = new List<IVisualTreeElement>();
|
var visualElements = new List<IVisualTreeElement>();
|
||||||
if (visualElement is IWindow window)
|
if (visualElement is IWindow window)
|
||||||
{
|
{
|
||||||
uiElement = window.Content?.ToPlatform();
|
// Get the UI.Xaml.Window so we catch everything in the app window rather than the frame which doesn't include modal content
|
||||||
|
var platformView = window.Handler?.PlatformView;
|
||||||
|
if (platformView is UI.Xaml.Window winUiWindow)
|
||||||
|
{
|
||||||
|
uiElement = winUiWindow.Content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (visualElement is IView view)
|
else if (visualElement is IView view)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,8 +8,10 @@ namespace Microsoft.Maui.Handlers
|
||||||
{
|
{
|
||||||
public partial class ImageHandler : ViewHandler<IImage, WImage>
|
public partial class ImageHandler : ViewHandler<IImage, WImage>
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
protected override WImage CreatePlatformView() => new WImage();
|
protected override WImage CreatePlatformView() => new WImage();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
protected override void ConnectHandler(WImage platformView)
|
protected override void ConnectHandler(WImage platformView)
|
||||||
{
|
{
|
||||||
platformView.ImageOpened += OnImageOpened;
|
platformView.ImageOpened += OnImageOpened;
|
||||||
|
@ -17,6 +19,7 @@ namespace Microsoft.Maui.Handlers
|
||||||
base.ConnectHandler(platformView);
|
base.ConnectHandler(platformView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
protected override void DisconnectHandler(WImage platformView)
|
protected override void DisconnectHandler(WImage platformView)
|
||||||
{
|
{
|
||||||
platformView.ImageOpened -= OnImageOpened;
|
platformView.ImageOpened -= OnImageOpened;
|
||||||
|
@ -25,25 +28,113 @@ namespace Microsoft.Maui.Handlers
|
||||||
SourceLoader.Reset();
|
SourceLoader.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public override bool NeedsContainer =>
|
public override bool NeedsContainer =>
|
||||||
VirtualView?.Background != null ||
|
VirtualView?.Background != null ||
|
||||||
|
VirtualView?.Aspect == Aspect.AspectFill ||
|
||||||
base.NeedsContainer;
|
base.NeedsContainer;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override void SetupContainer()
|
||||||
|
{
|
||||||
|
base.SetupContainer();
|
||||||
|
|
||||||
|
// VerticalAlignment only works when the child's Height is Auto
|
||||||
|
PlatformView.Height = Primitives.Dimension.Unset;
|
||||||
|
|
||||||
|
UpdateValue(nameof(IView.Height));
|
||||||
|
UpdateValue(nameof(IView.Width));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override void RemoveContainer()
|
||||||
|
{
|
||||||
|
base.RemoveContainer();
|
||||||
|
|
||||||
|
UpdateValue(nameof(IView.Height));
|
||||||
|
UpdateValue(nameof(IView.Width));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IView.Height"/> property to the platform-specific implementations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="view">The associated <see cref="Image"/> instance.</param>
|
||||||
|
public static void MapHeight(IImageHandler handler, IImage view)
|
||||||
|
{
|
||||||
|
// VerticalAlignment only works when the container's Height is set and the child's Height is Auto. The child's Height
|
||||||
|
// is set to Auto when the container is introduced.
|
||||||
|
if (handler.ContainerView is FrameworkElement container)
|
||||||
|
{
|
||||||
|
container.Height = view.Height;
|
||||||
|
handler.PlatformView.Height = Primitives.Dimension.Unset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ViewHandler.MapHeight(handler, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IView.Width"/> property to the platform-specific implementations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="view">The associated <see cref="Image"/> instance.</param>
|
||||||
|
public static void MapWidth(IImageHandler handler, IImage view)
|
||||||
|
{
|
||||||
|
if (handler.ContainerView is FrameworkElement container)
|
||||||
|
{
|
||||||
|
container.Width = view.Width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ViewHandler.MapWidth(handler, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IView.Background"/> property to the platform-specific implementations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="image">The associated <see cref="Image"/> instance.</param>
|
||||||
public static void MapBackground(IImageHandler handler, IImage image)
|
public static void MapBackground(IImageHandler handler, IImage image)
|
||||||
{
|
{
|
||||||
handler.UpdateValue(nameof(IViewHandler.ContainerView));
|
handler.UpdateValue(nameof(IViewHandler.ContainerView));
|
||||||
handler.ToPlatform().UpdateBackground(image);
|
handler.ToPlatform().UpdateBackground(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MapAspect(IImageHandler handler, IImage image) =>
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IImage.Aspect"/> property to the platform-specific implementations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="image">The associated <see cref="Image"/> instance.</param>
|
||||||
|
public static void MapAspect(IImageHandler handler, IImage image)
|
||||||
|
{
|
||||||
|
handler.UpdateValue(nameof(IViewHandler.ContainerView));
|
||||||
handler.PlatformView?.UpdateAspect(image);
|
handler.PlatformView?.UpdateAspect(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IImageSourcePart.IsAnimationPlaying"/> property to the platform-specific implementations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="image">The associated <see cref="Image"/> instance.</param>
|
||||||
public static void MapIsAnimationPlaying(IImageHandler handler, IImage image) =>
|
public static void MapIsAnimationPlaying(IImageHandler handler, IImage image) =>
|
||||||
handler.PlatformView?.UpdateIsAnimationPlaying(image);
|
handler.PlatformView?.UpdateIsAnimationPlaying(image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IImageSourcePart.Source"/> property to the platform-specific implementations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="image">The associated <see cref="Image"/> instance.</param>
|
||||||
public static void MapSource(IImageHandler handler, IImage image) =>
|
public static void MapSource(IImageHandler handler, IImage image) =>
|
||||||
MapSourceAsync(handler, image).FireAndForget(handler);
|
MapSourceAsync(handler, image).FireAndForget(handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps the abstract <see cref="IImageSourcePart.Source"/> property to the platform-specific implementations as an asynchronous operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">The associated handler.</param>
|
||||||
|
/// <param name="image">The associated <see cref="Image"/> instance.</param>
|
||||||
public static Task MapSourceAsync(IImageHandler handler, IImage image) =>
|
public static Task MapSourceAsync(IImageHandler handler, IImage image) =>
|
||||||
handler.SourceLoader.UpdateImageSourceAsync();
|
handler.SourceLoader.UpdateImageSourceAsync();
|
||||||
|
|
||||||
|
@ -66,4 +157,4 @@ namespace Microsoft.Maui.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@ namespace Microsoft.Maui.Handlers
|
||||||
{
|
{
|
||||||
#if __ANDROID__ || WINDOWS || TIZEN
|
#if __ANDROID__ || WINDOWS || TIZEN
|
||||||
[nameof(IImage.Background)] = MapBackground,
|
[nameof(IImage.Background)] = MapBackground,
|
||||||
|
#endif
|
||||||
|
#if WINDOWS
|
||||||
|
[nameof(IImage.Height)] = MapHeight,
|
||||||
|
[nameof(IImage.Width)] = MapWidth,
|
||||||
#endif
|
#endif
|
||||||
[nameof(IImage.Aspect)] = MapAspect,
|
[nameof(IImage.Aspect)] = MapAspect,
|
||||||
[nameof(IImage.IsAnimationPlaying)] = MapIsAnimationPlaying,
|
[nameof(IImage.IsAnimationPlaying)] = MapIsAnimationPlaying,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
|
using Android.Runtime;
|
||||||
|
|
||||||
|
namespace Microsoft.Maui.Platform;
|
||||||
|
|
||||||
|
internal class MauiLayerDrawable : LayerDrawable
|
||||||
|
{
|
||||||
|
public MauiLayerDrawable(params Drawable[] layers)
|
||||||
|
: base(layers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MauiLayerDrawable(nint javaReference, JniHandleOwnership transfer)
|
||||||
|
: base(javaReference, transfer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,9 @@ using Android.Views;
|
||||||
using Android.Views.InputMethods;
|
using Android.Views.InputMethods;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using AndroidX.AppCompat.Widget;
|
using AndroidX.AppCompat.Widget;
|
||||||
using AndroidX.ConstraintLayout.Helper.Widget;
|
|
||||||
using AndroidX.Core.Content;
|
using AndroidX.Core.Content;
|
||||||
using AndroidX.Core.View;
|
using AndroidX.Core.View;
|
||||||
using AndroidX.Window.Layout;
|
using Kotlin;
|
||||||
using Microsoft.Maui.ApplicationModel;
|
using Microsoft.Maui.ApplicationModel;
|
||||||
using Microsoft.Maui.Graphics;
|
using Microsoft.Maui.Graphics;
|
||||||
using Microsoft.Maui.Primitives;
|
using Microsoft.Maui.Primitives;
|
||||||
|
@ -188,62 +187,83 @@ namespace Microsoft.Maui.Platform
|
||||||
|
|
||||||
internal static void UpdateBackground(this EditText platformView, IView view)
|
internal static void UpdateBackground(this EditText platformView, IView view)
|
||||||
{
|
{
|
||||||
if (platformView is null || platformView.Background is null || platformView.Context is null)
|
if (platformView is null || platformView.Context is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove previous background gradient if any
|
// The user has removed the background from the platform view in platform code
|
||||||
if (platformView.Background is MauiDrawable mauiDrawable)
|
// so we need to make sure to do absolutely nothing.
|
||||||
|
if (platformView.Background is null)
|
||||||
{
|
{
|
||||||
platformView.Background = null;
|
return;
|
||||||
mauiDrawable.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platformView.Background is LayerDrawable layerDrawable)
|
// Get the current background of the edit text so we can make sure to not overwite it
|
||||||
|
// if it is not something that we have set in MAUI.
|
||||||
|
var previousDrawable = platformView.Background;
|
||||||
|
|
||||||
|
// Remove the previous MAUI background (if any).
|
||||||
|
if (previousDrawable is MauiDrawable || previousDrawable is MauiLayerDrawable)
|
||||||
{
|
{
|
||||||
platformView.Background = null;
|
platformView.Background = null;
|
||||||
layerDrawable.Dispose();
|
previousDrawable.Dispose();
|
||||||
|
previousDrawable = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Android will reset the padding when setting a Background drawable
|
// Get the new background from the virtual view
|
||||||
// So we need to reapply the padding after
|
|
||||||
var padLeft = platformView.PaddingLeft;
|
|
||||||
var padTop = platformView.PaddingTop;
|
|
||||||
var padRight = platformView.PaddingRight;
|
|
||||||
var padBottom = platformView.PaddingBottom;
|
|
||||||
|
|
||||||
var paint = view.Background;
|
var paint = view.Background;
|
||||||
|
|
||||||
Drawable? defaultBackgroundDrawable = ContextCompat.GetDrawable(platformView.Context, Resource.Drawable.abc_edit_text_material);
|
|
||||||
|
|
||||||
var previousDrawable = defaultBackgroundDrawable ?? platformView.Background;
|
|
||||||
var backgroundDrawable = paint.ToDrawable(platformView.Context);
|
var backgroundDrawable = paint.ToDrawable(platformView.Context);
|
||||||
|
|
||||||
if (previousDrawable is null)
|
if (backgroundDrawable is not null || previousDrawable is null)
|
||||||
platformView.Background = backgroundDrawable;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (backgroundDrawable is null)
|
// There is a new background to set, or we removed a previous background and
|
||||||
{
|
// now we have to re-apply just the default "line" background.
|
||||||
// The default Drawable of EditText is an InsetDrawable and setting the background we use a LayerDrawable
|
|
||||||
// to compose the custom background with the default behavior (bottom line).
|
|
||||||
//
|
|
||||||
// If the Background is null or is a ColorDrawable, a Custom Handler is being created, removing the default behavior.
|
|
||||||
// In this case, we don't want to reset the Drawable to the default one.
|
|
||||||
if (platformView.Background is not ColorDrawable)
|
|
||||||
platformView.Background = previousDrawable;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
LayerDrawable layer = new LayerDrawable(new Drawable[] { backgroundDrawable, previousDrawable });
|
// Regardless of what the new background is, we will need to apply the default
|
||||||
platformView.Background = layer;
|
// background "line" on top of it.
|
||||||
|
// If for some reason this returns null, then there is nothing we can do because
|
||||||
|
// AndroidX is probably broken since this is a resource from the AndroidX library.
|
||||||
|
var defaultBackground = ContextCompat.GetDrawable(platformView.Context, Resource.Drawable.abc_edit_text_material);
|
||||||
|
|
||||||
|
if (backgroundDrawable is not null)
|
||||||
|
{
|
||||||
|
// The user set some background, so we need to apply it below the default "line".
|
||||||
|
// If there is a broken AndroidX, then nothing we can do but just use ours.
|
||||||
|
SetBackground(platformView, defaultBackground is null
|
||||||
|
? new MauiLayerDrawable(backgroundDrawable)
|
||||||
|
: new MauiLayerDrawable(backgroundDrawable, defaultBackground));
|
||||||
|
}
|
||||||
|
else if (previousDrawable is null)
|
||||||
|
{
|
||||||
|
// The user set null in the virtual view (or did not set anything/kept the defaults)
|
||||||
|
// as we just removed a MAUI background from the platform view.
|
||||||
|
// This means we just use the default Material background (the "line").
|
||||||
|
SetBackground(platformView, defaultBackground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The drawable currently in use was not a MAUI drawable nor are we setting a new
|
||||||
|
// one so just do nothing and keep whatever the user has set in platform code.
|
||||||
|
}
|
||||||
|
|
||||||
// Apply previous padding
|
// A helper method to set the background and re-apply the padding since
|
||||||
platformView.SetPadding(padLeft, padTop, padRight, padBottom);
|
// Android will reset the padding when setting a Background drawable.
|
||||||
|
static void SetBackground(EditText platformView, Drawable? background)
|
||||||
|
{
|
||||||
|
// Cache the current padding
|
||||||
|
var padLeft = platformView.PaddingLeft;
|
||||||
|
var padTop = platformView.PaddingTop;
|
||||||
|
var padRight = platformView.PaddingRight;
|
||||||
|
var padBottom = platformView.PaddingBottom;
|
||||||
|
|
||||||
|
// Set the new background
|
||||||
|
platformView.Background = background;
|
||||||
|
|
||||||
|
// Apply previous padding
|
||||||
|
platformView.SetPadding(padLeft, padTop, padRight, padBottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateBackground(this AView platformView, Paint? background) =>
|
public static void UpdateBackground(this AView platformView, Paint? background) =>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Media.Imaging;
|
using Microsoft.UI.Xaml.Media.Imaging;
|
||||||
using WImage = Microsoft.UI.Xaml.Controls.Image;
|
using WImage = Microsoft.UI.Xaml.Controls.Image;
|
||||||
|
|
||||||
|
@ -14,6 +15,12 @@ namespace Microsoft.Maui.Platform
|
||||||
public static void UpdateAspect(this WImage imageView, IImage image)
|
public static void UpdateAspect(this WImage imageView, IImage image)
|
||||||
{
|
{
|
||||||
imageView.Stretch = image.Aspect.ToStretch();
|
imageView.Stretch = image.Aspect.ToStretch();
|
||||||
|
|
||||||
|
if (image.Aspect == Aspect.AspectFill)
|
||||||
|
{
|
||||||
|
imageView.VerticalAlignment = VerticalAlignment.Center;
|
||||||
|
imageView.HorizontalAlignment = HorizontalAlignment.Center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateIsAnimationPlaying(this WImage imageView, IImageSourcePart image)
|
public static void UpdateIsAnimationPlaying(this WImage imageView, IImageSourcePart image)
|
||||||
|
|
|
@ -83,6 +83,8 @@ override Microsoft.Maui.Handlers.HybridWebViewHandler.ConnectHandler(Microsoft.U
|
||||||
override Microsoft.Maui.Handlers.HybridWebViewHandler.CreatePlatformView() -> Microsoft.UI.Xaml.Controls.WebView2!
|
override Microsoft.Maui.Handlers.HybridWebViewHandler.CreatePlatformView() -> Microsoft.UI.Xaml.Controls.WebView2!
|
||||||
override Microsoft.Maui.Handlers.HybridWebViewHandler.DisconnectHandler(Microsoft.UI.Xaml.Controls.WebView2! platformView) -> void
|
override Microsoft.Maui.Handlers.HybridWebViewHandler.DisconnectHandler(Microsoft.UI.Xaml.Controls.WebView2! platformView) -> void
|
||||||
override Microsoft.Maui.Handlers.ImageHandler.ConnectHandler(Microsoft.UI.Xaml.Controls.Image! platformView) -> void
|
override Microsoft.Maui.Handlers.ImageHandler.ConnectHandler(Microsoft.UI.Xaml.Controls.Image! platformView) -> void
|
||||||
|
override Microsoft.Maui.Handlers.ImageHandler.RemoveContainer() -> void
|
||||||
|
override Microsoft.Maui.Handlers.ImageHandler.SetupContainer() -> void
|
||||||
override Microsoft.Maui.Handlers.MenuFlyoutHandler.DisconnectHandler(Microsoft.UI.Xaml.Controls.MenuFlyout! platformView) -> void
|
override Microsoft.Maui.Handlers.MenuFlyoutHandler.DisconnectHandler(Microsoft.UI.Xaml.Controls.MenuFlyout! platformView) -> void
|
||||||
override Microsoft.Maui.Layouts.FlexBasis.Equals(object? obj) -> bool
|
override Microsoft.Maui.Layouts.FlexBasis.Equals(object? obj) -> bool
|
||||||
override Microsoft.Maui.Layouts.FlexBasis.GetHashCode() -> int
|
override Microsoft.Maui.Layouts.FlexBasis.GetHashCode() -> int
|
||||||
|
@ -106,6 +108,8 @@ static Microsoft.Maui.Handlers.HybridWebViewHandler.MapEvaluateJavaScriptAsync(M
|
||||||
static Microsoft.Maui.Handlers.HybridWebViewHandler.Mapper -> Microsoft.Maui.IPropertyMapper<Microsoft.Maui.IHybridWebView!, Microsoft.Maui.Handlers.IHybridWebViewHandler!>!
|
static Microsoft.Maui.Handlers.HybridWebViewHandler.Mapper -> Microsoft.Maui.IPropertyMapper<Microsoft.Maui.IHybridWebView!, Microsoft.Maui.Handlers.IHybridWebViewHandler!>!
|
||||||
static Microsoft.Maui.Handlers.HybridWebViewHandler.MapSendRawMessage(Microsoft.Maui.Handlers.IHybridWebViewHandler! handler, Microsoft.Maui.IHybridWebView! hybridWebView, object? arg) -> void
|
static Microsoft.Maui.Handlers.HybridWebViewHandler.MapSendRawMessage(Microsoft.Maui.Handlers.IHybridWebViewHandler! handler, Microsoft.Maui.IHybridWebView! hybridWebView, object? arg) -> void
|
||||||
static Microsoft.Maui.Handlers.LayoutHandler.MapInputTransparent(Microsoft.Maui.ILayoutHandler! handler, Microsoft.Maui.ILayout! layout) -> void
|
static Microsoft.Maui.Handlers.LayoutHandler.MapInputTransparent(Microsoft.Maui.ILayoutHandler! handler, Microsoft.Maui.ILayout! layout) -> void
|
||||||
|
static Microsoft.Maui.Handlers.ImageHandler.MapHeight(Microsoft.Maui.Handlers.IImageHandler! handler, Microsoft.Maui.IImage! view) -> void
|
||||||
|
static Microsoft.Maui.Handlers.ImageHandler.MapWidth(Microsoft.Maui.Handlers.IImageHandler! handler, Microsoft.Maui.IImage! view) -> void
|
||||||
static Microsoft.Maui.Handlers.SearchBarHandler.MapIsSpellCheckEnabled(Microsoft.Maui.Handlers.ISearchBarHandler! handler, Microsoft.Maui.ISearchBar! searchBar) -> void
|
static Microsoft.Maui.Handlers.SearchBarHandler.MapIsSpellCheckEnabled(Microsoft.Maui.Handlers.ISearchBarHandler! handler, Microsoft.Maui.ISearchBar! searchBar) -> void
|
||||||
static Microsoft.Maui.Handlers.SwipeItemMenuItemHandler.MapSourceAsync(Microsoft.Maui.Handlers.ISwipeItemMenuItemHandler! handler, Microsoft.Maui.ISwipeItemMenuItem! image) -> System.Threading.Tasks.Task!
|
static Microsoft.Maui.Handlers.SwipeItemMenuItemHandler.MapSourceAsync(Microsoft.Maui.Handlers.ISwipeItemMenuItemHandler! handler, Microsoft.Maui.ISwipeItemMenuItem! image) -> System.Threading.Tasks.Task!
|
||||||
static Microsoft.Maui.Hosting.MauiHandlersCollectionExtensions.AddHandler<TType>(this Microsoft.Maui.Hosting.IMauiHandlersCollection! handlersCollection, System.Func<System.IServiceProvider!, Microsoft.Maui.IElementHandler!>! handlerImplementationFactory) -> Microsoft.Maui.Hosting.IMauiHandlersCollection!
|
static Microsoft.Maui.Hosting.MauiHandlersCollectionExtensions.AddHandler<TType>(this Microsoft.Maui.Hosting.IMauiHandlersCollection! handlersCollection, System.Func<System.IServiceProvider!, Microsoft.Maui.IElementHandler!>! handlerImplementationFactory) -> Microsoft.Maui.Hosting.IMauiHandlersCollection!
|
||||||
|
|