Merge branch '4.8.0' into main
This commit is contained in:
Коммит
f11d099354
|
@ -27,6 +27,7 @@ namespace Xamarin.Forms.ControlGallery.WindowsUniversal
|
|||
/// </summary>
|
||||
sealed partial class App
|
||||
{
|
||||
public static bool RunningAsUITests { get; private set; }
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
|
@ -44,12 +45,12 @@ namespace Xamarin.Forms.ControlGallery.WindowsUniversal
|
|||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
/* uncomment if you want to run tests without preloading
|
||||
* issues list or change other behavior based on if tests
|
||||
* are running in UI Harness
|
||||
* if (!String.IsNullOrWhiteSpace(e.Arguments) &&
|
||||
if (!String.IsNullOrWhiteSpace(e.Arguments) &&
|
||||
e.Arguments.Contains("RunningAsUITests"))
|
||||
Controls.App.PreloadTestCasesIssuesList = false;*/
|
||||
{
|
||||
RunningAsUITests = true;
|
||||
Controls.App.PreloadTestCasesIssuesList = false;
|
||||
}
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
|
|
|
@ -29,13 +29,14 @@ namespace Xamarin.Forms.ControlGallery.WindowsUniversal
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
// some tests need to window to be large enough to click on things
|
||||
// can we make this only open to window size for UI Tests?
|
||||
//var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
|
||||
//var scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
|
||||
//var size = new Windows.Foundation.Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
|
||||
//ApplicationView.PreferredLaunchViewSize = size;
|
||||
//ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
||||
if (Xamarin.Forms.ControlGallery.WindowsUniversal.App.RunningAsUITests)
|
||||
{
|
||||
var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
|
||||
var scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
|
||||
var size = new Windows.Foundation.Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
|
||||
ApplicationView.PreferredLaunchViewSize = size;
|
||||
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
||||
}
|
||||
|
||||
|
||||
_app = new Controls.App();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{AC257966-9368-478A-9DF4-F0D28E320FE3}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
|
@ -20,12 +20,10 @@
|
|||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D5A43FC916D476D1E32C2DADF178F6206989B043</PackageCertificateThumbprint>
|
||||
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<RuntimeIdentifiers>win10-arm;win10-arm-aot;win10-x86;win10-x86-aot;win10-x64;win10-x64-aot</RuntimeIdentifiers>
|
||||
<GenerateAppxPackageOnBuild>False</GenerateAppxPackageOnBuild>
|
||||
<GenerateAppxPackageOnBuild Condition="'$(AppxBundle)' != 'Always'">False</GenerateAppxPackageOnBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -280,6 +278,9 @@
|
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
|
|
Двоичные данные
Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx
Normal file
Двоичные данные
Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx
Normal file
Двоичный файл не отображается.
|
@ -65,7 +65,7 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void UpdatingSourceOfDisposedListViewDoesNotCrash()
|
||||
public void WebViewEvalCrashesOnAndroidWithLongString()
|
||||
{
|
||||
RunningApp.WaitForElement("navigatedLabel");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Xamarin.Forms.Controls.Issues.Issue10908"
|
||||
Title="Issue 10908">
|
||||
<ContentPage.Content>
|
||||
<ListView
|
||||
x:Name ="lstView"
|
||||
IsGroupingEnabled="true"
|
||||
HasUnevenRows="True"
|
||||
SeparatorVisibility="None"
|
||||
GroupDisplayBinding="{Binding LongName}"
|
||||
GroupShortNameBinding="{Binding ShortName}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell>
|
||||
<SwipeView>
|
||||
<SwipeView.LeftItems>
|
||||
<SwipeItem
|
||||
BackgroundColor="Red"
|
||||
IconImageSource="icon.png"
|
||||
Text="Delete"/>
|
||||
</SwipeView.LeftItems>
|
||||
<StackLayout
|
||||
HeightRequest="60">
|
||||
<Label Text="{Binding Name}" />
|
||||
<Label Text="{Binding Comment}" />
|
||||
</StackLayout>
|
||||
</SwipeView>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
|
@ -0,0 +1,77 @@
|
|||
using System.Collections.ObjectModel;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 10908, "[Bug] [iOS]SwipeView not working on Grouped ListView", PlatformAffected.iOS)]
|
||||
public partial class Issue10908 : ContentPage
|
||||
{
|
||||
public Issue10908()
|
||||
{
|
||||
#if APP
|
||||
InitializeComponent ();
|
||||
|
||||
Grouped = new ObservableCollection<GroupedIssue10908Model>();
|
||||
|
||||
var veggieGroup = new GroupedIssue10908Model() { LongName = "vegetables", ShortName = "v" };
|
||||
var fruitGroup = new GroupedIssue10908Model() { LongName = "fruit", ShortName = "f" };
|
||||
var veggie1Group = new GroupedIssue10908Model() { LongName = "vegetables1", ShortName = "v1" };
|
||||
var fruit1Group = new GroupedIssue10908Model() { LongName = "fruit1", ShortName = "f1" };
|
||||
var veggie2Group = new GroupedIssue10908Model() { LongName = "vegetables2", ShortName = "v2" };
|
||||
var fruit2Group = new GroupedIssue10908Model() { LongName = "fruit2", ShortName = "f2" };
|
||||
veggieGroup.Add(new Issue10908Model() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
|
||||
veggieGroup.Add(new Issue10908Model() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
|
||||
veggieGroup.Add(new Issue10908Model() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
|
||||
veggieGroup.Add(new Issue10908Model() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
|
||||
fruitGroup.Add(new Issue10908Model() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
|
||||
fruitGroup.Add(new Issue10908Model() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
|
||||
fruitGroup.Add(new Issue10908Model() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
|
||||
|
||||
veggie1Group.Add(new Issue10908Model() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
|
||||
veggie1Group.Add(new Issue10908Model() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
|
||||
veggie1Group.Add(new Issue10908Model() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
|
||||
veggie1Group.Add(new Issue10908Model() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
|
||||
fruit1Group.Add(new Issue10908Model() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
|
||||
fruit1Group.Add(new Issue10908Model() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
|
||||
fruit1Group.Add(new Issue10908Model() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
|
||||
|
||||
veggie2Group.Add(new Issue10908Model() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
|
||||
veggie2Group.Add(new Issue10908Model() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
|
||||
veggie2Group.Add(new Issue10908Model() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
|
||||
veggie2Group.Add(new Issue10908Model() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
|
||||
fruit2Group.Add(new Issue10908Model() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
|
||||
fruit2Group.Add(new Issue10908Model() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
|
||||
fruit2Group.Add(new Issue10908Model() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
|
||||
|
||||
Grouped.Add(veggieGroup);
|
||||
Grouped.Add(fruitGroup);
|
||||
Grouped.Add(veggie1Group);
|
||||
Grouped.Add(fruit1Group);
|
||||
Grouped.Add(veggie2Group);
|
||||
Grouped.Add(fruit2Group);
|
||||
|
||||
lstView.ItemsSource = Grouped;
|
||||
#endif
|
||||
}
|
||||
|
||||
ObservableCollection<GroupedIssue10908Model> Grouped { get; set; }
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public class Issue10908Model
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public bool IsReallyAVeggie { get; set; }
|
||||
public string Image { get; set; }
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public class GroupedIssue10908Model : ObservableCollection<Issue10908Model>
|
||||
{
|
||||
public string LongName { get; set; }
|
||||
public string ShortName { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
using Xamarin.Forms.Internals;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.Label)]
|
||||
#endif
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 11272,
|
||||
"[Bug] Crash XF for Mac 4.7.0.1080",
|
||||
PlatformAffected.macOS)]
|
||||
public class Issue11272 : TestContentPage
|
||||
{
|
||||
public Issue11272()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
Title = "Issue 11272";
|
||||
|
||||
var layout = new StackLayout();
|
||||
|
||||
var instructions = new Label
|
||||
{
|
||||
Padding = 12,
|
||||
BackgroundColor = Color.Black,
|
||||
TextColor = Color.White,
|
||||
Text = "Without exception, this test has passed."
|
||||
};
|
||||
|
||||
var errorLabel1 = new Label()
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
FormattedText = new FormattedString
|
||||
{
|
||||
Spans =
|
||||
{
|
||||
new Span()
|
||||
{
|
||||
Text = "🔔🌀 Issue 11272",
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var errorLabel2 = new Label()
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
FormattedText = new FormattedString
|
||||
{
|
||||
Spans =
|
||||
{
|
||||
new Span()
|
||||
{
|
||||
TextColor = Color.Red,
|
||||
Text = "🔔🌀 Issue 11272 (Using TextColor)",
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
layout.Children.Add(instructions);
|
||||
layout.Children.Add(errorLabel1);
|
||||
layout.Children.Add(errorLabel2);
|
||||
|
||||
Content = layout;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,17 +10,18 @@
|
|||
x:Class="Xamarin.Forms.Controls.Issues.Issue2172">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<Button Text="Toggle Vertical Alignment (center, end, start - box heights will change)" Clicked="Button_OnClicked"/>
|
||||
<Label FontSize="25" Text="Using new measure code, no text should be clipped"></Label>
|
||||
<ScrollView VerticalScrollBarVisibility="Always">
|
||||
<Grid BackgroundColor="Green" Padding="5">
|
||||
<StackLayout>
|
||||
<StackLayout>
|
||||
<Entry FontSize="30" Text="{Binding Number}" />
|
||||
<Entry FontSize="25" Text="Nested" />
|
||||
<Entry FontSize="25" />
|
||||
<Entry x:Name="BoundEntry" FontSize="30" Text="{Binding Number}" />
|
||||
<Entry x:Name="NestedEntry" FontSize="25" Text="Nested" />
|
||||
<Entry x:Name="EmptyEntry" FontSize="25" />
|
||||
<Label FontSize="25" Text="Label"/>
|
||||
<Editor FontSize="25" Text="Editor"></Editor>
|
||||
<Editor FontSize="25" Text="Auto Size Editor, add more lines to test." AutoSize="TextChanges"></Editor>
|
||||
<Editor x:Name="StandardEditor" FontSize="25" Text="Editor"></Editor>
|
||||
<Editor x:Name="AutoSizeEditor" FontSize="25" Text="Auto Size Editor, add more lines to test." AutoSize="TextChanges"></Editor>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using System;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
|
@ -19,6 +20,25 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
{
|
||||
public string Number => "Bound Text";
|
||||
}
|
||||
#if APP
|
||||
void Button_OnClicked(object sender, EventArgs e)
|
||||
{
|
||||
BoundEntry.HeightRequest = 100;
|
||||
NestedEntry.HeightRequest = 100;
|
||||
EmptyEntry.HeightRequest = 100;
|
||||
|
||||
TextAlignment newAlignment;
|
||||
if (BoundEntry.VerticalTextAlignment == TextAlignment.Center)
|
||||
newAlignment = TextAlignment.End;
|
||||
else if (BoundEntry.VerticalTextAlignment == TextAlignment.End)
|
||||
newAlignment = TextAlignment.Start;
|
||||
else
|
||||
newAlignment = TextAlignment.Center;
|
||||
BoundEntry.VerticalTextAlignment = newAlignment;
|
||||
NestedEntry.VerticalTextAlignment = newAlignment;
|
||||
EmptyEntry.VerticalTextAlignment = newAlignment;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public class Issue2172OldEntry : Entry
|
||||
|
|
|
@ -7,10 +7,12 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
{
|
||||
#if APP
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#endif
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 5108, "iOS: Frame with HasShadow set to true and BackgroundColor alpha < 1 casts shadow on all child views", PlatformAffected.iOS)]
|
||||
public partial class Issue5108 : TestContentPage
|
||||
{
|
||||
#if APP
|
||||
public Issue5108()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -20,11 +22,6 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
BackgroundButton.Clicked += BackgroundButton_Clicked;
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MarginButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (myframe.Margin.Top == 20)
|
||||
|
@ -57,6 +54,11 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
else
|
||||
myframe.BackgroundColor = initialColor.Value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
|
||||
static Issue6698LongLifecycleModel _longLifecycleModel;
|
||||
AbsoluteLayout _container;
|
||||
ListView _listView;
|
||||
|
||||
static Issue6698LongLifecycleModel GetLongLifecycleModel() =>
|
||||
_longLifecycleModel ?? (_longLifecycleModel = new Issue6698LongLifecycleModel());
|
||||
|
|
|
@ -0,0 +1,372 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.ComponentModel;
|
||||
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 8503, "[Bug] Text is not visible on Entry element after animation finished",
|
||||
PlatformAffected.UWP)]
|
||||
public class Issue8503 : TestContentPage
|
||||
{
|
||||
Entry isolatedEntry;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
Title = "Issue 8503 [UWP] - text in Entry not visible until receiving focus";
|
||||
ScrollView scrollView = new ScrollView();
|
||||
|
||||
StackLayout layout = new StackLayout { Margin = new Thickness(20, 0) };
|
||||
layout.BindingContext = this;
|
||||
|
||||
Label isolatedHeader = new Label { Text = "Isolated Bug", Margin = new Thickness(0, 20), FontSize = 18 };
|
||||
Label isolatedInstructions = new Label
|
||||
{
|
||||
Text = "This is the bug isolated. To test:\n" +
|
||||
"Click on the button below, to show Entry for Isolated Bug.\n" +
|
||||
"An Entry appears.\n" +
|
||||
"Check that the entry contains text 'This text should be visible, even before acquiring focus'.\n" +
|
||||
"If it does, the issue is fixed.\n" +
|
||||
"If it does not, check if the text appears if the entry receives focus.\n" +
|
||||
"If it does, the bug is not fixed."
|
||||
};
|
||||
isolatedEntry = new Entry { Text = "This text should be visible, even before acquiring focus", IsVisible = false };
|
||||
|
||||
Button isolatedShowEntryButton = new Button { Text = "Click to show Entry for Isolated Bug" };
|
||||
isolatedShowEntryButton.Clicked += IsolatedShowEntryButton_Clicked;
|
||||
|
||||
layout.Children.Add(isolatedHeader);
|
||||
layout.Children.Add(isolatedInstructions);
|
||||
layout.Children.Add(isolatedEntry);
|
||||
layout.Children.Add(isolatedShowEntryButton);
|
||||
|
||||
Label issueHeader = new Label { Text = "Reported Bug", Margin = new Thickness(0, 20), FontSize = 18 };
|
||||
Label issueInstructions = new Label
|
||||
{
|
||||
Text = "This is the bug as reported with an example\n" +
|
||||
"Click on the login-action button.\n" +
|
||||
"An Entry for a UserName appears with a little translating animation.\n" +
|
||||
"Check that the entry contains text 'user name goes here'.\n" +
|
||||
"If it does, the issue is fixed.\n" +
|
||||
"If it does not, check if the text appears if the entry receives focus.\n" +
|
||||
"If it does, the bug is there."
|
||||
};
|
||||
|
||||
LoginAnimateBehavior bugBehavior = new LoginAnimateBehavior
|
||||
{
|
||||
EasingType = EEasingType.SinInOut,
|
||||
AnimationType = EAnimationType.Translation
|
||||
};
|
||||
|
||||
StackLayout issueStackLayout = new StackLayout();
|
||||
LoginAnimationStackLayout animatedStackLayout = new LoginAnimationStackLayout
|
||||
{
|
||||
IsVisible = false
|
||||
};
|
||||
animatedStackLayout.SetBinding(LoginAnimationStackLayout.VisibleProperty, nameof(IsUserNameEntryVisible));
|
||||
animatedStackLayout.Behaviors.Add(bugBehavior);
|
||||
|
||||
Entry loginUserNameEntry = new Entry
|
||||
{
|
||||
IsEnabled = true
|
||||
};
|
||||
loginUserNameEntry.SetBinding(Entry.TextProperty, nameof(UserName));
|
||||
|
||||
Button loginButton = new Button
|
||||
{
|
||||
Text = "Login_Action",
|
||||
WidthRequest = 150
|
||||
};
|
||||
loginButton.Clicked += LoginButton_Clicked;
|
||||
|
||||
animatedStackLayout.Children.Add(loginUserNameEntry);
|
||||
|
||||
issueStackLayout.Children.Add(animatedStackLayout);
|
||||
issueStackLayout.Children.Add(loginButton);
|
||||
|
||||
layout.Children.Add(issueHeader);
|
||||
layout.Children.Add(issueInstructions);
|
||||
layout.Children.Add(issueStackLayout);
|
||||
|
||||
scrollView.Content = layout;
|
||||
Content = scrollView;
|
||||
}
|
||||
|
||||
private void IsolatedShowEntryButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
isolatedEntry.IsVisible = true;
|
||||
}
|
||||
|
||||
bool isUserNameEntryVisible;
|
||||
public bool IsUserNameEntryVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
return isUserNameEntryVisible;
|
||||
}
|
||||
set
|
||||
{
|
||||
isUserNameEntryVisible = value;
|
||||
OnPropertyChanged(nameof(IsUserNameEntryVisible));
|
||||
}
|
||||
}
|
||||
|
||||
string userName;
|
||||
public string UserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
set
|
||||
{
|
||||
userName = value;
|
||||
OnPropertyChanged(nameof(UserName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void LoginButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
UserName = "username goes here";
|
||||
IsUserNameEntryVisible = true;
|
||||
}
|
||||
|
||||
public class LoginAnimationStackLayout : StackLayout
|
||||
{
|
||||
public static readonly BindableProperty VisibleProperty = BindableProperty.Create(nameof(Visible), typeof(bool), typeof(LoginAnimationStackLayout), defaultBindingMode: BindingMode.TwoWay, defaultValue: false, propertyChanged: (b, o, n) => ((LoginAnimationStackLayout)b).OnVisibileChanged((bool)o, (bool)n));
|
||||
|
||||
public bool Visible
|
||||
{
|
||||
get
|
||||
{
|
||||
var obj = GetValue(VisibleProperty);
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)obj;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(VisibleProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnVisibileChanged(bool oldvalue, bool newvalue)
|
||||
{
|
||||
Visible = newvalue;
|
||||
}
|
||||
}
|
||||
|
||||
public class LoginAnimateBehavior : BaseAnimationBehavior
|
||||
{
|
||||
private static double? yPosition;
|
||||
|
||||
protected override async void AnimateItem(object sender, EventArgs e)
|
||||
{
|
||||
PropertyChangedEventArgs prop = e as PropertyChangedEventArgs;
|
||||
|
||||
if (prop == null || !prop.PropertyName.Equals(nameof(LoginAnimationStackLayout.Visible), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await DoAnimationByType(AnimationType, associatedObject, ToEasing(EasingType), Scale);
|
||||
}
|
||||
|
||||
private static async Task DoAnimationByType(EAnimationType animationType, View obj, Easing easing, double scale)
|
||||
{
|
||||
LoginAnimationStackLayout stack = obj as LoginAnimationStackLayout;
|
||||
if (stack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (animationType)
|
||||
{
|
||||
case EAnimationType.Translation:
|
||||
await DoTranslation(stack, obj, easing);
|
||||
break;
|
||||
|
||||
case EAnimationType.Scale:
|
||||
await DoScale(stack, easing, scale);
|
||||
break;
|
||||
|
||||
default:
|
||||
stack.IsVisible = stack.Visible;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task DoTranslation(LoginAnimationStackLayout stackLayout, View obj, Easing easing)
|
||||
{
|
||||
if (stackLayout.Visible)
|
||||
{
|
||||
stackLayout.IsVisible = true;
|
||||
|
||||
if (!yPosition.HasValue)
|
||||
{
|
||||
yPosition = obj.TranslationY;
|
||||
}
|
||||
|
||||
await stackLayout.TranslateTo(obj.TranslationX, obj.TranslationY - 10, 10, easing);
|
||||
await stackLayout.TranslateTo(obj.TranslationX, obj.TranslationY + 10, 900, easing);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!yPosition.HasValue)
|
||||
{
|
||||
yPosition = obj.TranslationY;
|
||||
}
|
||||
|
||||
await stackLayout.TranslateTo(obj.TranslationX, obj.TranslationY, 10, easing);
|
||||
await stackLayout.TranslateTo(obj.TranslationX, obj.TranslationY - 20, 900, easing);
|
||||
|
||||
obj.TranslationY = yPosition.Value;
|
||||
|
||||
stackLayout.IsVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task DoScale(LoginAnimationStackLayout stackLayout, Easing easing, double scale)
|
||||
{
|
||||
if (stackLayout.Visible)
|
||||
{
|
||||
stackLayout.IsVisible = true;
|
||||
|
||||
await stackLayout.ScaleTo(scale, 250, easing);
|
||||
await stackLayout.ScaleTo(1.00, 250, easing);
|
||||
}
|
||||
else
|
||||
{
|
||||
await stackLayout.ScaleTo(1.00, 250, easing);
|
||||
await stackLayout.ScaleTo(scale, 250, easing);
|
||||
|
||||
stackLayout.IsVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseAnimationBehavior : Behavior<View>
|
||||
{
|
||||
protected View associatedObject;
|
||||
|
||||
public static readonly BindableProperty EasingTypeProperty = BindableProperty.Create(nameof(EasingType), typeof(EEasingType), typeof(BaseAnimationBehavior), defaultValue: EEasingType.Linear, propertyChanged: (b, o, n) => OnEasingFunctionChanged(b, (EEasingType)o, (EEasingType)n));
|
||||
public static readonly BindableProperty ScaleProperty = BindableProperty.Create(nameof(Scale), typeof(double), typeof(BaseAnimationBehavior), defaultValue: 1.25);
|
||||
public static readonly BindableProperty AnimationTypeProperty = BindableProperty.Create(nameof(AnimationType), typeof(EAnimationType), typeof(BaseAnimationBehavior), defaultValue: default(EAnimationType));
|
||||
|
||||
public EEasingType EasingType
|
||||
{
|
||||
get { return (EEasingType)GetValue(EasingTypeProperty); }
|
||||
set { SetValue(EasingTypeProperty, value); }
|
||||
}
|
||||
|
||||
public double Scale
|
||||
{
|
||||
get { return (double)GetValue(ScaleProperty); }
|
||||
set { SetValue(ScaleProperty, value); }
|
||||
}
|
||||
|
||||
public EAnimationType AnimationType
|
||||
{
|
||||
get
|
||||
{
|
||||
EAnimationType animationType = default(EAnimationType);
|
||||
string data = GetValue(AnimationTypeProperty)?.ToString();
|
||||
|
||||
Enum.TryParse(data, out animationType);
|
||||
|
||||
return animationType;
|
||||
}
|
||||
set { SetValue(AnimationTypeProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnAttachedTo(View bindable)
|
||||
{
|
||||
associatedObject = bindable;
|
||||
associatedObject.PropertyChanged += AnimateItem;
|
||||
}
|
||||
|
||||
protected override void OnDetachingFrom(View bindable)
|
||||
{
|
||||
associatedObject.PropertyChanged -= AnimateItem;
|
||||
}
|
||||
|
||||
protected static Easing ToEasing(EEasingType easingType)
|
||||
{
|
||||
switch (easingType)
|
||||
{
|
||||
case EEasingType.BounceIn:
|
||||
return Easing.BounceIn;
|
||||
case EEasingType.BounceOut:
|
||||
return Easing.BounceOut;
|
||||
case EEasingType.CubicIn:
|
||||
return Easing.CubicIn;
|
||||
case EEasingType.CubicInOut:
|
||||
return Easing.CubicInOut;
|
||||
case EEasingType.CubicOut:
|
||||
return Easing.CubicOut;
|
||||
case EEasingType.Linear:
|
||||
return Easing.Linear;
|
||||
case EEasingType.SinIn:
|
||||
return Easing.SinIn;
|
||||
case EEasingType.SinInOut:
|
||||
return Easing.SinInOut;
|
||||
case EEasingType.SinOut:
|
||||
return Easing.SinOut;
|
||||
case EEasingType.SpringIn:
|
||||
return Easing.SpringIn;
|
||||
case EEasingType.SpringOut:
|
||||
return Easing.SpringOut;
|
||||
default:
|
||||
return Easing.Linear;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnEasingFunctionChanged(BindableObject bindable, EEasingType oldvalue, EEasingType newvalue)
|
||||
{
|
||||
var obj = bindable as BaseAnimationBehavior;
|
||||
if (obj == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
obj.EasingType = newvalue;
|
||||
}
|
||||
|
||||
protected abstract void AnimateItem(object sender, EventArgs e);
|
||||
}
|
||||
|
||||
public enum EAnimationType
|
||||
{
|
||||
None,
|
||||
Translation,
|
||||
Rotate,
|
||||
Scale
|
||||
}
|
||||
|
||||
public enum EEasingType
|
||||
{
|
||||
Linear,
|
||||
SinOut,
|
||||
SinIn,
|
||||
SinInOut,
|
||||
CubicIn,
|
||||
CubicOut,
|
||||
CubicInOut,
|
||||
BounceOut,
|
||||
BounceIn,
|
||||
SpringIn,
|
||||
SpringOut,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 8787, "[Bug] Entry text initially invisible on UWP",
|
||||
PlatformAffected.UWP)]
|
||||
public partial class Issue8787 : TestContentPage
|
||||
{
|
||||
public Issue8787()
|
||||
{
|
||||
#if APP
|
||||
InitializeComponent();
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<controls:TestContentPage
|
||||
xmlns:controls="clr-namespace:Xamarin.Forms.Controls"
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Xamarin.Forms.Controls.Issues.Issue8787"
|
||||
Title="Issue 8787 - Entry text not immediately visible"
|
||||
x:Name="Instance"
|
||||
BindingContext="{x:Reference Instance}"
|
||||
BackgroundColor="Beige">
|
||||
<Grid>
|
||||
<ScrollView Grid.Row="0">
|
||||
<StackLayout>
|
||||
<ContentView>
|
||||
<StackLayout>
|
||||
<StackLayout>
|
||||
<Label Text="Check that the text in the yellow Entry below is immediately visible. If it does not appear before the Entry gains focus or the window is resized, the issue is not fixed." Margin="10"/>
|
||||
<Entry Text="This text ought to be visible immediately" HeightRequest="50" BackgroundColor="Yellow"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</controls:TestContentPage>
|
|
@ -18,6 +18,7 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.ManualReview)]
|
||||
[Category(UITestCategories.CarouselView)]
|
||||
#endif
|
||||
#if APP
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
|
|
|
@ -446,6 +446,40 @@ namespace Xamarin.Forms.Controls
|
|||
get { return _app.TestServer; }
|
||||
}
|
||||
|
||||
public void TestSetup(Type testType, bool isolate)
|
||||
{
|
||||
if (isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(testType, this);
|
||||
}
|
||||
|
||||
public void TestTearDown(bool isolate)
|
||||
{
|
||||
if (isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
ScreenshotFailure();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
public void ScreenshotFailure()
|
||||
{
|
||||
(_app as Core.UITests.WinDriverApp).ScreenshotFailure();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __IOS__
|
||||
|
||||
public bool IsTablet
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Reflection;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using IOPath = System.IO.Path;
|
||||
using NUnit.Framework.Interfaces;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
|
@ -197,7 +198,7 @@ namespace Xamarin.Forms.Controls
|
|||
app.Tap(q => q.Button("Go to Test Cases"));
|
||||
app.WaitForElement(q => q.Raw("* marked:'TestCasesIssueList'"));
|
||||
|
||||
app.EnterText(q => q.Raw("* marked:'SearchBarGo'"), cellName);
|
||||
app.EnterText(q => q.Raw("* marked:'SearchBarGo'"), $"{cellName}");
|
||||
|
||||
app.WaitForElement(q => q.Raw("* marked:'SearchButton'"));
|
||||
app.Tap(q => q.Raw("* marked:'SearchButton'"));
|
||||
|
@ -331,26 +332,13 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -377,26 +365,13 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -425,26 +400,13 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -473,26 +435,13 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -518,26 +467,13 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -569,26 +505,13 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -822,27 +745,15 @@ namespace Xamarin.Forms.Controls
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.BeginIsolate();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSetup.EnsureMemory();
|
||||
AppSetup.EnsureConnection();
|
||||
}
|
||||
|
||||
AppSetup.NavigateToIssue(GetType(), RunningApp);
|
||||
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
if (Isolate)
|
||||
{
|
||||
AppSetup.EndIsolate();
|
||||
}
|
||||
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
|
||||
}
|
||||
|
||||
public void ShowFlyout(string flyoutIcon = FlyoutIconAutomationId, bool usingSwipe = false, bool testForFlyoutIcon = true)
|
||||
{
|
||||
if (testForFlyoutIcon)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Issue9428.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue9419.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8262.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8787.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8899.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8551.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8836.cs" />
|
||||
|
@ -214,6 +215,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Issue8203.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8222.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8167.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8503.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8263.xaml.cs">
|
||||
<DependentUpon>Issue8263.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
@ -1435,10 +1437,12 @@
|
|||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11031.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10940.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10908.xaml.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11132.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11113.xaml.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10182.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11107.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11272.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
|
||||
|
@ -1564,6 +1568,7 @@
|
|||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue4040.xaml">
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue8787.xaml" />
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue9771.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
|
@ -1677,6 +1682,9 @@
|
|||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue9555.xaml">
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue10908.xaml">
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue11113.xaml">
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -17,7 +17,6 @@ namespace Xamarin.Forms.Controls
|
|||
public class App : Application
|
||||
{
|
||||
public const string AppName = "XamarinFormsControls";
|
||||
static string s_insightsKey;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public static int IOSVersion = -1;
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Xamarin.Forms.Controls
|
|||
{
|
||||
public class NativeBindingGalleryPage : ContentPage
|
||||
{
|
||||
public StackLayout Layout { get; set; }
|
||||
public new StackLayout Layout { get; set; }
|
||||
public bool NativeControlsAdded { get; set; }
|
||||
|
||||
NestedNativeViewModel ViewModel { get; set; }
|
||||
|
|
|
@ -2,7 +2,7 @@ namespace Xamarin.Forms.Controls
|
|||
{
|
||||
public partial class NestedNativeControlGalleryPage : ContentPage
|
||||
{
|
||||
public StackLayout Layout { get; set; }
|
||||
public new StackLayout Layout { get; set; }
|
||||
|
||||
public bool NativeControlsAdded { get; set; }
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ namespace Xamarin.Forms.Controls
|
|||
Content = new StackLayout { Children = { btn, btnRemove, new Grid { Children = { zoomContainer }, Padding = new Thickness (20) } } };
|
||||
}
|
||||
|
||||
double _currentScale = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -505,18 +505,10 @@ namespace Xamarin.Forms.Controls
|
|||
SetValue(AutomationProperties.NameProperty, "Core Pages");
|
||||
}
|
||||
|
||||
NavigationBehavior navigationBehavior;
|
||||
|
||||
async Task PushPage(Page contentPage)
|
||||
{
|
||||
if (navigationBehavior == NavigationBehavior.PushModalAsync)
|
||||
{
|
||||
await Navigation.PushModalAsync(contentPage);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Navigation.PushAsync(contentPage);
|
||||
}
|
||||
await Navigation.PushAsync(contentPage);
|
||||
}
|
||||
|
||||
readonly Dictionary<string, GalleryPageFactory> _titleToPage;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Xamarin.Forms.Controls
|
|||
|
||||
protected StateViewContainer<T> IsEnabledStateViewContainer { get; private set; }
|
||||
|
||||
protected StackLayout Layout { get; private set; }
|
||||
protected new StackLayout Layout { get; private set; }
|
||||
|
||||
internal CoreGalleryPage()
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Xamarin.Forms.Controls
|
|||
var textFontSizeContainer = new ViewContainer<Editor>(Test.Editor.FontSize, new Editor { Text = "I have default size text" });
|
||||
var textFontSizeDefaultContainer = new ViewContainer<Editor>(Test.Editor.FontSize, new Editor { Text = "I also have default size text" });
|
||||
textFontSizeDefaultContainer.View.FontSize = Device.GetNamedSize(NamedSize.Default, textFontSizeDefaultContainer.View);
|
||||
var textFontSizeLargeContainer = new ViewContainer<Editor>(Test.Editor.FontSize, new Editor { Text = "I have size 48 (huge) text", FontSize = 48 });
|
||||
var textFontSizeLargeContainer = new ViewContainer<Editor>(Test.Editor.FontSize, new Editor { Text = "I have size 48 (huge) text", FontSize = 48, Placeholder = "This is a placeholder" });
|
||||
|
||||
var textColorContainer = new ViewContainer<Editor>(Test.Editor.TextColor,
|
||||
new Editor { Text = "I should have red text", TextColor = Color.Red });
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace Xamarin.Forms.Controls
|
|||
get { return _rowHeight; }
|
||||
set
|
||||
{
|
||||
if (value != null && value != _rowHeight)
|
||||
if (value != _rowHeight)
|
||||
{
|
||||
_rowHeight = value;
|
||||
OnPropertyChanged();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
|
@ -25,7 +26,7 @@ namespace Xamarin.Forms.Controls
|
|||
|
||||
string _name;
|
||||
string _shortName;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public new event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public string Name
|
||||
{
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace Xamarin.Forms.Controls
|
|||
public Func<ImageSource> Getter { get; set; }
|
||||
}
|
||||
|
||||
class RootPage : ContentPage
|
||||
new class RootPage : ContentPage
|
||||
{
|
||||
public RootPage()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using Xamarin.Forms.Shapes;
|
||||
|
||||
namespace Xamarin.Forms.Controls.GalleryPages.ShapesGalleries
|
||||
{
|
||||
public class SpiralDemoPage : ContentPage
|
||||
{
|
||||
protected Polyline polyline;
|
||||
|
||||
public SpiralDemoPage()
|
||||
{
|
||||
polyline = new Polyline
|
||||
{
|
||||
Stroke = Color.Orange,
|
||||
StrokeThickness = 5
|
||||
};
|
||||
Content = polyline;
|
||||
|
||||
SizeChanged += OnPageSizeChanged;
|
||||
}
|
||||
|
||||
void OnPageSizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (Width <= 0 || Height <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
polyline.Points.Clear();
|
||||
|
||||
double radius = Math.Min(Width / 2, Height / 2);
|
||||
Point center = new Point(Width / 2, Height / 2);
|
||||
|
||||
PointCollection points = polyline.Points;
|
||||
polyline.Points = null;
|
||||
|
||||
for (double angle = 0; angle < 3600; angle += 1)
|
||||
{
|
||||
double scaledRadius = radius * angle / 3600;
|
||||
double radians = Math.PI * angle / 180;
|
||||
double x = center.X + scaledRadius * Math.Cos(radians);
|
||||
double y = center.Y + scaledRadius * Math.Sin(radians);
|
||||
points.Add(new Point(x, y));
|
||||
}
|
||||
|
||||
polyline.Points = points;
|
||||
}
|
||||
}
|
||||
|
||||
public class AnimateShapeGallery : SpiralDemoPage
|
||||
{
|
||||
public AnimateShapeGallery()
|
||||
{
|
||||
Title = "Animate Shape Gallery";
|
||||
|
||||
polyline.StrokeDashArray.Add(4);
|
||||
polyline.StrokeDashArray.Add(2);
|
||||
double total = polyline.StrokeDashArray[0] + polyline.StrokeDashArray[1];
|
||||
|
||||
Device.StartTimer(TimeSpan.FromMilliseconds(15), () =>
|
||||
{
|
||||
double secs = DateTime.Now.TimeOfDay.TotalSeconds;
|
||||
polyline.StrokeDashOffset = total * (secs % 1);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.ShapesGalleries
|
|||
GalleryBuilder.NavButton("Path LayoutOptions Gallery", () => new PathLayoutOptionsGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Transform Playground", () => new TransformPlaygroundGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Path Transform using string (TypeConverter) Gallery", () => new PathTransformStringGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Animate Shape Gallery", () => new AnimateShapeGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Clip Gallery", () => new ClipGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Clip Views Gallery", () => new ClipViewsGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Add/Remove Clip Gallery", () => new AddRemoveClipGallery(), Navigation),
|
||||
|
|
|
@ -2,10 +2,6 @@ namespace Xamarin.Forms.Controls
|
|||
{
|
||||
public class MainPageLifeCycleTests : ContentPage
|
||||
{
|
||||
int _numTimesStarted;
|
||||
int _numTimesSlept;
|
||||
int _numTimesResumed;
|
||||
|
||||
readonly StackLayout _numTimesStartedLayout;
|
||||
readonly StackLayout _numTimesSleptLayout;
|
||||
readonly StackLayout _numTimesResumedLayout;
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Forms.Controls
|
||||
{
|
||||
|
@ -192,9 +193,15 @@ namespace Xamarin.Forms.Controls
|
|||
FilterIssues(_filter);
|
||||
}
|
||||
|
||||
public void FilterIssues(string filter = null)
|
||||
public async void FilterIssues(string filter = null)
|
||||
{
|
||||
filter = filter?.Trim();
|
||||
_filter = filter;
|
||||
|
||||
// Deeeee bounce
|
||||
await Task.Delay(10);
|
||||
if (_filter != filter)
|
||||
return;
|
||||
|
||||
PageToAction.Clear();
|
||||
if(String.IsNullOrWhiteSpace(filter) && !Controls.App.PreloadTestCasesIssuesList)
|
||||
|
@ -281,7 +288,7 @@ namespace Xamarin.Forms.Controls
|
|||
AutomationId = "SearchButton",
|
||||
Command = new Command (() => {
|
||||
try {
|
||||
TestCaseScreen.PageToAction[searchBar.Text] ();
|
||||
TestCaseScreen.PageToAction[searchBar.Text?.Trim()] ();
|
||||
} catch (Exception e) {
|
||||
System.Diagnostics.Debug.WriteLine (e.Message);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ namespace Xamarin.Forms.Controls.XamStore
|
|||
{
|
||||
On<iOS>().SetUseSafeArea(true);
|
||||
|
||||
var searchHandlerKey = nameof(SearchHandler);
|
||||
|
||||
TestedTypes.Add(SearchHandlerKey, (AddSearchHandler, new NamedAction[] { new NamedAction { Name = nameof(Focus), Action = FocusUnfocusSearchHandler } }));
|
||||
|
||||
_searchHandler = TestedTypes[SearchHandlerKey].ctor() as SearchHandler;
|
||||
|
|
|
@ -7,7 +7,10 @@ using System.Drawing.Imaging;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Appium.Windows;
|
||||
using OpenQA.Selenium.Interactions;
|
||||
|
@ -21,6 +24,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
public class WinDriverApp : IApp
|
||||
{
|
||||
public const string AppName = "Xamarin.Forms.ControlGallery.WindowsUniversal";
|
||||
public static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
readonly Dictionary<string, string> _controlNameToTag = new Dictionary<string, string>
|
||||
{
|
||||
|
@ -57,6 +61,12 @@ namespace Xamarin.Forms.Core.UITests
|
|||
Init(WindowsTestBase.CreateWindowsDriver());
|
||||
}
|
||||
|
||||
public void RestartApp()
|
||||
{
|
||||
_session.CloseApp();
|
||||
Init(WindowsTestBase.CreateWindowsDriver());
|
||||
}
|
||||
|
||||
public void Back()
|
||||
{
|
||||
QueryWindows("Back").First().Click();
|
||||
|
@ -64,7 +74,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
|
||||
public void ClearText(Func<AppQuery, AppQuery> query)
|
||||
{
|
||||
QueryWindows(query).First().Clear();
|
||||
SwapInUsefulElement(QueryWindows(query).First()).Clear();
|
||||
}
|
||||
|
||||
public void ClearText(Func<AppQuery, AppWebQuery> query)
|
||||
|
@ -74,7 +84,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
|
||||
public void ClearText(string marked)
|
||||
{
|
||||
QueryWindows(marked).First().Clear();
|
||||
SwapInUsefulElement(QueryWindows(marked).First()).Clear();
|
||||
}
|
||||
|
||||
public void ClearText()
|
||||
|
@ -126,16 +136,25 @@ namespace Xamarin.Forms.Core.UITests
|
|||
.Perform();
|
||||
}
|
||||
|
||||
static RemoteWebElement SwapInUsefulElement(WindowsElement element)
|
||||
{
|
||||
// AutoSuggestBox on UWP has some interaction issues with WebDriver
|
||||
// The AutomationID is set on the control group not the actual TextBox
|
||||
// This retrieves the actual TextBox which makes the behavior more consistent
|
||||
var isAutoSuggest = element?.FindElementsByXPath("//*[contains(@AutomationId,'_AutoSuggestBox')]")?.FirstOrDefault();
|
||||
return isAutoSuggest ?? element;
|
||||
}
|
||||
|
||||
public void EnterText(Func<AppQuery, AppQuery> query, string text)
|
||||
{
|
||||
var result = QueryWindows(query).First();
|
||||
result.SendKeys(text);
|
||||
SwapInUsefulElement(result).SendKeys(text);
|
||||
}
|
||||
|
||||
public void EnterText(string marked, string text)
|
||||
{
|
||||
var results = QueryWindows(marked).First();
|
||||
results.SendKeys(text);
|
||||
var result = QueryWindows(marked).First();
|
||||
SwapInUsefulElement(result).SendKeys(text);
|
||||
}
|
||||
|
||||
public void EnterText(Func<AppQuery, AppWebQuery> query, string text)
|
||||
|
@ -287,6 +306,20 @@ namespace Xamarin.Forms.Core.UITests
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public void ScreenshotFailure()
|
||||
{
|
||||
if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
|
||||
{
|
||||
string filename = $"{TestContext.CurrentContext.Test.FullName}.png";
|
||||
Screenshot screenshot = _session.GetScreenshot();
|
||||
screenshot.SaveAsFile(filename, ScreenshotImageFormat.Png);
|
||||
var file = new FileInfo(filename);
|
||||
|
||||
TestContext.AddTestAttachment(file.FullName, TestContext.CurrentContext.Test.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public FileInfo Screenshot(string title)
|
||||
{
|
||||
// TODO hartez 2017/07/18 10:16:56 Verify that this is working; seems a bit too simple
|
||||
|
@ -294,7 +327,10 @@ namespace Xamarin.Forms.Core.UITests
|
|||
|
||||
Screenshot screenshot = _session.GetScreenshot();
|
||||
screenshot.SaveAsFile(filename, ScreenshotImageFormat.Png);
|
||||
return new FileInfo(filename);
|
||||
var file = new FileInfo(filename);
|
||||
|
||||
TestContext.AddTestAttachment(file.FullName, title);
|
||||
return file;
|
||||
}
|
||||
|
||||
public void ScrollDown(Func<AppQuery, AppQuery> withinQuery = null, ScrollStrategy strategy = ScrollStrategy.Auto,
|
||||
|
@ -786,7 +822,12 @@ namespace Xamarin.Forms.Core.UITests
|
|||
}
|
||||
|
||||
ReadOnlyCollection<WindowsElement> candidates = QueryWindows(AppName);
|
||||
_viewPort = candidates[3]; // We really just want the viewport; skip the full window, title bar, min/max buttons...
|
||||
|
||||
// When you go full screen there are less candidates because certain elements go away on the window
|
||||
if (candidates.Count >= 4)
|
||||
_viewPort = candidates[3]; // We really just want the viewport; skip the full window, title bar, min/max buttons...
|
||||
else
|
||||
_viewPort = candidates.Last();
|
||||
|
||||
int xOffset = _viewPort.Coordinates.LocationInViewport.X;
|
||||
|
||||
|
@ -887,7 +928,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
|
||||
void ScrollTo(WinQuery toQuery, WinQuery withinQuery, TimeSpan? timeout = null, bool down = true)
|
||||
{
|
||||
timeout = timeout ?? TimeSpan.FromSeconds(5);
|
||||
timeout = timeout ?? DefaultTimeout;
|
||||
DateTime start = DateTime.Now;
|
||||
|
||||
while (true)
|
||||
|
@ -969,7 +1010,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
{
|
||||
Rect = ToAppRect(windowsElement),
|
||||
Label = windowsElement.Id, // Not entirely sure about this one
|
||||
Description = windowsElement.Text, // or this one
|
||||
Description = SwapInUsefulElement(windowsElement).Text, // or this one
|
||||
Enabled = windowsElement.Enabled,
|
||||
Id = windowsElement.Id
|
||||
};
|
||||
|
@ -980,7 +1021,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
string timeoutMessage = null,
|
||||
TimeSpan? timeout = null, TimeSpan? retryFrequency = null)
|
||||
{
|
||||
timeout = timeout ?? TimeSpan.FromSeconds(5);
|
||||
timeout = timeout ?? DefaultTimeout;
|
||||
retryFrequency = retryFrequency ?? TimeSpan.FromMilliseconds(500);
|
||||
timeoutMessage = timeoutMessage ?? "Timed out on query.";
|
||||
|
||||
|
@ -994,7 +1035,7 @@ namespace Xamarin.Forms.Core.UITests
|
|||
if (elapsed >= timeout.Value.Ticks)
|
||||
{
|
||||
Debug.WriteLine($">>>>> {elapsed} ticks elapsed, timeout value is {timeout.Value.Ticks}");
|
||||
|
||||
|
||||
throw new TimeoutException(timeoutMessage);
|
||||
}
|
||||
|
||||
|
|
|
@ -105,8 +105,10 @@ namespace Xamarin.Forms
|
|||
if (shell == null)
|
||||
return true;
|
||||
|
||||
bool defaultShow = ShellItemController.GetItems().Count > 1;
|
||||
return shell.GetEffectiveValue<bool>(Shell.TabBarIsVisibleProperty, () => defaultShow, null, displayedPage);
|
||||
if (ShellItemController.GetItems().Count <= 1)
|
||||
return false;
|
||||
|
||||
return shell.GetEffectiveValue<bool>(Shell.TabBarIsVisibleProperty, () => true, null, displayedPage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace Xamarin.Forms.Material.iOS
|
|||
{
|
||||
base.LayoutSubviews();
|
||||
|
||||
if (Control == null) return;
|
||||
// try get the radius for this size
|
||||
var min = NMath.Min(Control.Bounds.Width, Control.Bounds.Height);
|
||||
var stroke = min / _strokeRatio;
|
||||
|
@ -145,4 +146,4 @@ namespace Xamarin.Forms.Material.iOS
|
|||
Control.StopAnimating();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -419,14 +419,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
if (DisplayedPage == null)
|
||||
return;
|
||||
|
||||
bool visible = ShellItemController.ShowTabs;
|
||||
using (var menu = _bottomView.Menu)
|
||||
{
|
||||
if (menu.Size() == 1)
|
||||
visible = false;
|
||||
}
|
||||
|
||||
_bottomView.Visibility = visible ? ViewStates.Visible : ViewStates.Gone;
|
||||
_bottomView.Visibility = ShellItemController.ShowTabs ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateStroke();
|
||||
UpdateStrokeThickness();
|
||||
UpdateStrokeDashArray();
|
||||
UpdateStrokeDashOffset();
|
||||
UpdateStrokeLineCap();
|
||||
UpdateStrokeLineJoin();
|
||||
}
|
||||
|
@ -66,6 +67,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateStrokeThickness();
|
||||
else if (args.PropertyName == Shape.StrokeDashArrayProperty.PropertyName)
|
||||
UpdateStrokeDashArray();
|
||||
else if (args.PropertyName == Shape.StrokeDashOffsetProperty.PropertyName)
|
||||
UpdateStrokeDashOffset();
|
||||
else if (args.PropertyName == Shape.StrokeLineCapProperty.PropertyName)
|
||||
UpdateStrokeLineCap();
|
||||
else if (args.PropertyName == Shape.StrokeLineJoinProperty.PropertyName)
|
||||
|
@ -112,6 +115,11 @@ namespace Xamarin.Forms.Platform.Android
|
|||
Control.UpdateStrokeDashArray(Element.StrokeDashArray.ToArray());
|
||||
}
|
||||
|
||||
void UpdateStrokeDashOffset()
|
||||
{
|
||||
Control.UpdateStrokeDashOffset((float)Element.StrokeDashOffset);
|
||||
}
|
||||
|
||||
void UpdateStrokeLineCap()
|
||||
{
|
||||
PenLineCap lineCap = Element.StrokeLineCap;
|
||||
|
@ -169,6 +177,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
float _strokeWidth;
|
||||
float[] _strokeDash;
|
||||
float _strokeDashOffset;
|
||||
|
||||
Stretch _aspect;
|
||||
|
||||
|
@ -269,13 +278,23 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
_strokeWidth = _density * strokeWidth;
|
||||
_drawable.Paint.StrokeWidth = _strokeWidth;
|
||||
UpdatePathStrokeBounds();
|
||||
UpdateStrokeDash();
|
||||
}
|
||||
|
||||
public void UpdateStrokeDashArray(float[] dash)
|
||||
{
|
||||
_strokeDash = dash;
|
||||
UpdateStrokeDash();
|
||||
}
|
||||
|
||||
public void UpdateStrokeDashOffset(float strokeDashOffset)
|
||||
{
|
||||
_strokeDashOffset = strokeDashOffset;
|
||||
UpdateStrokeDash();
|
||||
}
|
||||
|
||||
public void UpdateStrokeDash()
|
||||
{
|
||||
if (_strokeDash != null && _strokeDash.Length > 1)
|
||||
{
|
||||
float[] strokeDash = new float[_strokeDash.Length];
|
||||
|
@ -283,7 +302,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
for (int i = 0; i < _strokeDash.Length; i++)
|
||||
strokeDash[i] = _strokeDash[i] * _strokeWidth;
|
||||
|
||||
_drawable.Paint.SetPathEffect(new DashPathEffect(strokeDash, 0));
|
||||
_drawable.Paint.SetPathEffect(new DashPathEffect(strokeDash, _strokeDashOffset * _strokeWidth));
|
||||
}
|
||||
else
|
||||
_drawable.Paint.SetPathEffect(null);
|
||||
|
|
|
@ -9,8 +9,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
public class ItemContentControl : ContentControl
|
||||
{
|
||||
View _view;
|
||||
VisualElement _visualElement;
|
||||
IVisualElementRenderer _renderer;
|
||||
DataTemplate _currentTemplate;
|
||||
|
||||
public ItemContentControl()
|
||||
{
|
||||
|
@ -104,11 +105,11 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
base.OnContentChanged(oldContent, newContent);
|
||||
|
||||
if (oldContent != null && _view != null)
|
||||
_view.MeasureInvalidated -= OnViewMeasureInvalidated;
|
||||
if (oldContent != null && _visualElement != null)
|
||||
_visualElement.MeasureInvalidated -= OnViewMeasureInvalidated;
|
||||
|
||||
if (newContent != null && _view != null)
|
||||
_view.MeasureInvalidated += OnViewMeasureInvalidated;
|
||||
if (newContent != null && _visualElement != null)
|
||||
_visualElement.MeasureInvalidated += OnViewMeasureInvalidated;
|
||||
}
|
||||
|
||||
internal void Realize()
|
||||
|
@ -129,14 +130,28 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
return;
|
||||
}
|
||||
|
||||
_view = FormsDataTemplate.CreateContent(dataContext, container) as View;
|
||||
_view.BindingContext = dataContext;
|
||||
_renderer = Platform.CreateRenderer(_view);
|
||||
Platform.SetRenderer(_view, _renderer);
|
||||
if (_renderer?.ContainerElement == null || _currentTemplate != formsTemplate)
|
||||
{
|
||||
// If the content has never been realized (i.e., this is a new instance),
|
||||
// or if we need to switch DataTemplates (because this instance is being recycled)
|
||||
// then we'll need to create the content from the template
|
||||
_visualElement = formsTemplate.CreateContent(dataContext, container) as VisualElement;
|
||||
_visualElement.BindingContext = dataContext;
|
||||
_renderer = Platform.CreateRenderer(_visualElement);
|
||||
Platform.SetRenderer(_visualElement, _renderer);
|
||||
|
||||
// Keep track of the template in case this instance gets reused later
|
||||
_currentTemplate = formsTemplate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are reusing this ItemContentControl and we can reuse the Element
|
||||
_visualElement = _renderer.Element;
|
||||
_visualElement.BindingContext = dataContext;
|
||||
}
|
||||
|
||||
Content = _renderer.ContainerElement;
|
||||
|
||||
itemsView?.AddLogicalChild(_view);
|
||||
itemsView?.AddLogicalChild(_visualElement);
|
||||
}
|
||||
|
||||
internal void UpdateIsSelected(bool isSelected)
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
AcceptsReturn = true,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Style = Windows.UI.Xaml.Application.Current.Resources["FormsTextBoxStyle"] as Windows.UI.Xaml.Style,
|
||||
VerticalContentAlignment = VerticalAlignment.Top
|
||||
VerticalContentAlignment = VerticalAlignment.Top,
|
||||
UpdateVerticalAlignmentOnLoad = false
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
InputScope _passwordInputScope;
|
||||
InputScope _numericPasswordInputScope;
|
||||
Border _borderElement;
|
||||
Windows.UI.Xaml.Controls.ScrollViewer _scrollViewer;
|
||||
Windows.UI.Xaml.Controls.Grid _rootGrid;
|
||||
Windows.UI.Xaml.VisualState _DeleteButtonVisibleState;
|
||||
Windows.UI.Xaml.VisualStateGroup _DeleteButtonVisibleStateGroups;
|
||||
|
@ -63,6 +64,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
TextChanged += OnTextChanged;
|
||||
SelectionChanged += OnSelectionChanged;
|
||||
IsEnabledChanged += OnIsEnabledChanged;
|
||||
Loaded += OnLoaded;
|
||||
RegisterPropertyChangedCallback(VerticalContentAlignmentProperty, OnVerticalContentAlignmentChanged);
|
||||
}
|
||||
|
||||
void OnIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||
|
@ -70,6 +73,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateEnabled();
|
||||
}
|
||||
|
||||
public bool UpdateVerticalAlignmentOnLoad { get; set; } = true;
|
||||
|
||||
public bool ClearButtonVisible
|
||||
{
|
||||
get { return (bool)GetValue(ClearButtonVisibleProperty); }
|
||||
|
@ -167,6 +172,30 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
if (_DeleteButtonVisibleStateGroups != null)
|
||||
_DeleteButtonVisibleState = _DeleteButtonVisibleStateGroups.States.SingleOrDefault(s => s.Name == "ButtonVisible");
|
||||
}
|
||||
|
||||
_scrollViewer= (Windows.UI.Xaml.Controls.ScrollViewer)GetTemplateChild("ContentElement");
|
||||
}
|
||||
|
||||
void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Set the vertical alignment on load, because setting it in the FormsTextBoxStyle causes text display issues
|
||||
// But the editor has display issues if you do set the vertical alignment here, so the flag allows renderer using
|
||||
// the text box to control this
|
||||
UpdateTemplateScrollViewerVerticalAlignment();
|
||||
}
|
||||
|
||||
void OnVerticalContentAlignmentChanged(DependencyObject sender, DependencyProperty dp)
|
||||
{
|
||||
UpdateTemplateScrollViewerVerticalAlignment();
|
||||
}
|
||||
|
||||
void UpdateTemplateScrollViewerVerticalAlignment()
|
||||
{
|
||||
if (_scrollViewer != null && UpdateVerticalAlignmentOnLoad)
|
||||
{
|
||||
_scrollViewer.VerticalAlignment = VerticalContentAlignment;
|
||||
Focus(FocusState.Programmatic);
|
||||
}
|
||||
}
|
||||
|
||||
void DelayObfuscation()
|
||||
|
|
|
@ -211,8 +211,7 @@
|
|||
ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" FontWeight="Normal"
|
||||
Margin="0,0,0,8" Grid.Row="0" Visibility="Collapsed" x:DeferLoadStrategy="Lazy" />
|
||||
<ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw"
|
||||
|
||||
<ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw"
|
||||
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
|
||||
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
||||
IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
|
||||
|
@ -221,7 +220,7 @@
|
|||
Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1"
|
||||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
|
||||
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
<ContentControl x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2"
|
||||
Content="{TemplateBinding PlaceholderText}"
|
||||
Foreground="{TemplateBinding PlaceholderForegroundBrush}" IsHitTestVisible="False"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<ResourceDictionary Source="PageControlStyle.xaml" />
|
||||
<ResourceDictionary Source="FormsProgressBarStyle.xaml" />
|
||||
<ResourceDictionary Source="FormsTextBoxStyle.xaml" />
|
||||
<ResourceDictionary Source="FormsCheckBoxStyle.xaml" />
|
||||
<ResourceDictionary Source="FormsCheckBoxStyle.xaml" />
|
||||
<ResourceDictionary Source="FormsAutoSuggestBoxStyle.xaml" />
|
||||
<ResourceDictionary Source="MasterDetailControlStyle.xaml" />
|
||||
<ResourceDictionary Source="TabbedPageStyle.xaml" />
|
||||
|
|
|
@ -113,6 +113,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateIsSpellCheckEnabled();
|
||||
UpdateInputScope();
|
||||
UpdateMaxLength();
|
||||
SetAutomationId(Element.AutomationId);
|
||||
|
||||
// If the Forms VisualStateManager is in play or the user wants to disable the Forms legacy
|
||||
// color stuff, then the underlying textbox should just use the Forms VSM states
|
||||
|
@ -121,6 +122,18 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|| !Element.OnThisPlatform().GetIsLegacyColorModeEnabled();
|
||||
}
|
||||
|
||||
protected override void SetAutomationId(string id)
|
||||
{
|
||||
base.SetAutomationId(id);
|
||||
|
||||
if (_queryTextBox == null)
|
||||
return;
|
||||
|
||||
// This allow us to locate the actual TextBox for Automation purposes
|
||||
// It's more reliable to interact directly with the TextBox
|
||||
_queryTextBox.SetAutomationPropertiesAutomationId($"{id}_AutoSuggestBox");
|
||||
}
|
||||
|
||||
void OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs e)
|
||||
{
|
||||
// Modifies the text of the control if it does not match the query.
|
||||
|
|
|
@ -154,7 +154,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
#else
|
||||
internal static readonly NSColor Black = NSColor.Black;
|
||||
internal static readonly NSColor SeventyPercentGrey = NSColor.FromRgba(0.7f, 0.7f, 0.7f, 1);
|
||||
internal static readonly NSColor LabelColor = NSColor.Black;
|
||||
internal static readonly NSColor LabelColor = NSColor.Black.UsingColorSpace("NSCalibratedRGBColorSpace");
|
||||
internal static readonly NSColor AccentColor = Color.FromRgba(50, 79, 133, 255).ToNSColor();
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
using System;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
internal class PageLifecycleManager : IDisposable
|
||||
{
|
||||
NSObject _activateObserver;
|
||||
NSObject _resignObserver;
|
||||
bool _disposed;
|
||||
bool _appeared;
|
||||
IPageController _pageController;
|
||||
|
||||
public PageLifecycleManager(IPageController pageController)
|
||||
{
|
||||
_pageController = pageController ?? throw new ArgumentNullException("You need to provide a Page Element");
|
||||
|
||||
_activateObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidBecomeActiveNotification, n =>
|
||||
{
|
||||
if (CheckIfWeAreTheCurrentPage())
|
||||
HandlePageAppearing();
|
||||
});
|
||||
|
||||
_resignObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.WillResignActiveNotification, n =>
|
||||
{
|
||||
if (CheckIfWeAreTheCurrentPage())
|
||||
HandlePageDisappearing();
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (_activateObserver != null)
|
||||
{
|
||||
NSNotificationCenter.DefaultCenter.RemoveObserver(_activateObserver);
|
||||
_activateObserver = null;
|
||||
}
|
||||
|
||||
if (_resignObserver != null)
|
||||
{
|
||||
NSNotificationCenter.DefaultCenter.RemoveObserver(_resignObserver);
|
||||
_resignObserver = null;
|
||||
}
|
||||
|
||||
HandlePageDisappearing();
|
||||
|
||||
_pageController = null;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public void HandlePageAppearing()
|
||||
{
|
||||
if (_appeared)
|
||||
return;
|
||||
|
||||
_appeared = true;
|
||||
_pageController?.SendAppearing();
|
||||
|
||||
}
|
||||
|
||||
public void HandlePageDisappearing()
|
||||
{
|
||||
if (!_appeared || _pageController == null)
|
||||
return;
|
||||
|
||||
_appeared = false;
|
||||
_pageController.SendDisappearing();
|
||||
}
|
||||
|
||||
bool CheckIfWeAreTheCurrentPage()
|
||||
{
|
||||
if (_pageController.RealParent is IPageContainer<Page> multipage)
|
||||
return multipage.CurrentPage == _pageController;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
// create label so it can get updated during the initial setup loop
|
||||
_placeholderLabel = new UILabel
|
||||
{
|
||||
BackgroundColor = UIColor.Clear
|
||||
BackgroundColor = UIColor.Clear,
|
||||
Frame = new RectangleF(0, 0, Frame.Width, Frame.Height),
|
||||
Lines = 0
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -63,6 +65,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
protected internal override void UpdatePlaceholderText()
|
||||
{
|
||||
_placeholderLabel.Text = Element.Placeholder;
|
||||
|
||||
_placeholderLabel.SizeToFit();
|
||||
}
|
||||
|
||||
protected internal override void UpdateCharacterSpacing()
|
||||
|
@ -72,7 +76,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
if(textAttr != null)
|
||||
TextView.AttributedText = textAttr;
|
||||
|
||||
var placeHolder = TextView.AttributedText.AddCharacterSpacing(Element.Placeholder, Element.CharacterSpacing);
|
||||
var placeHolder = _placeholderLabel.AttributedText.AddCharacterSpacing(Element.Placeholder, Element.CharacterSpacing);
|
||||
|
||||
if(placeHolder != null)
|
||||
_placeholderLabel.AttributedText = placeHolder;
|
||||
|
@ -112,7 +116,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
new NSObject[] { _placeholderLabel }, new NSObject[] { new NSString("_placeholderLabel") })
|
||||
);
|
||||
|
||||
_placeholderLabel.TranslatesAutoresizingMaskIntoConstraints = false;
|
||||
_placeholderLabel.TranslatesAutoresizingMaskIntoConstraints = true;
|
||||
_placeholderLabel.AttributedText = _placeholderLabel.AttributedText.AddCharacterSpacing(Element.Placeholder, Element.CharacterSpacing);
|
||||
|
||||
Control.AddConstraints(hConstraints);
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CoreGraphics;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using Xamarin.Forms.Internals;
|
||||
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
|
||||
|
@ -19,7 +20,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
public class NavigationRenderer : UINavigationController, IVisualElementRenderer, IEffectControlProvider
|
||||
{
|
||||
internal const string UpdateToolbarButtons = "Xamarin.UpdateToolbarButtons";
|
||||
bool _appeared;
|
||||
bool _ignorePopCall;
|
||||
bool _loaded;
|
||||
MasterDetailPage _parentMasterDetailPage;
|
||||
|
@ -32,8 +32,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UIImage _defaultNavBarShadowImage;
|
||||
UIImage _defaultNavBarBackImage;
|
||||
bool _disposed;
|
||||
PageLifecycleManager _pageLifecycleManager;
|
||||
|
||||
[Preserve(Conditional = true)]
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public NavigationRenderer() : base(typeof(FormsNavigationBar), null)
|
||||
{
|
||||
MessagingCenter.Subscribe<IVisualElementRenderer>(this, UpdateToolbarButtons, sender =>
|
||||
|
@ -71,8 +72,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
Element = element;
|
||||
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
|
||||
|
||||
if (element != null)
|
||||
element.SendViewInitialized(NativeView);
|
||||
_pageLifecycleManager = new PageLifecycleManager(Element as IPageController);
|
||||
|
||||
element?.SendViewInitialized(NativeView);
|
||||
|
||||
EffectUtilities.RegisterEffectControlProvider(this, oldElement, element);
|
||||
}
|
||||
|
@ -132,11 +134,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
public override void ViewDidAppear(bool animated)
|
||||
{
|
||||
if (!_appeared)
|
||||
{
|
||||
_appeared = true;
|
||||
PageController?.SendAppearing();
|
||||
}
|
||||
_pageLifecycleManager?.HandlePageAppearing();
|
||||
|
||||
base.ViewDidAppear(animated);
|
||||
|
||||
|
@ -157,11 +155,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
base.ViewDidDisappear(animated);
|
||||
|
||||
if (!_appeared || Element == null)
|
||||
return;
|
||||
|
||||
_appeared = false;
|
||||
PageController.SendDisappearing();
|
||||
_pageLifecycleManager?.HandlePageDisappearing();
|
||||
}
|
||||
|
||||
public override void ViewDidLayoutSubviews()
|
||||
|
@ -284,16 +278,12 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
navPage.PopToRootRequested -= OnPopToRootRequested;
|
||||
navPage.RemovePageRequested -= OnRemovedPageRequested;
|
||||
navPage.InsertPageBeforeRequested -= OnInsertPageBeforeRequested;
|
||||
|
||||
_pageLifecycleManager?.Dispose();
|
||||
_pageLifecycleManager = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing && _appeared)
|
||||
{
|
||||
PageController.SendDisappearing();
|
||||
|
||||
_appeared = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
|
||||
|
@ -372,7 +362,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
ParentingViewController CreateViewControllerForPage(Page page)
|
||||
{
|
||||
if (Platform.GetRenderer(page) == null)
|
||||
|
|
|
@ -11,11 +11,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
public class PageRenderer : UIViewController, IVisualElementRenderer, IEffectControlProvider, IAccessibilityElementsController, IShellContentInsetObserver
|
||||
{
|
||||
bool _appeared;
|
||||
bool _disposed;
|
||||
EventTracker _events;
|
||||
VisualElementPackager _packager;
|
||||
VisualElementTracker _tracker;
|
||||
PageLifecycleManager _pageLifecycleManager;
|
||||
|
||||
// storing this into a local variable causes it to not get collected. Do not delete this please
|
||||
PageContainer _pageContainer;
|
||||
|
@ -119,6 +119,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
|
||||
|
||||
_pageLifecycleManager = new PageLifecycleManager(Element as IPageController);
|
||||
|
||||
if (element != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(element.AutomationId))
|
||||
|
@ -195,33 +197,31 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
base.ViewDidAppear(animated);
|
||||
|
||||
if (_appeared || _disposed)
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_appeared = true;
|
||||
UpdateStatusBarPrefersHidden();
|
||||
|
||||
if (Forms.RespondsToSetNeedsUpdateOfHomeIndicatorAutoHidden)
|
||||
SetNeedsUpdateOfHomeIndicatorAutoHidden();
|
||||
|
||||
if (Element.Parent is CarouselPage)
|
||||
return;
|
||||
|
||||
Page.SendAppearing();
|
||||
_pageLifecycleManager?.HandlePageAppearing();
|
||||
}
|
||||
|
||||
public override void ViewDidDisappear(bool animated)
|
||||
{
|
||||
base.ViewDidDisappear(animated);
|
||||
|
||||
if (!_appeared || _disposed)
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_appeared = false;
|
||||
|
||||
if (Element.Parent is CarouselPage)
|
||||
return;
|
||||
|
||||
Page.SendDisappearing();
|
||||
_pageLifecycleManager?.HandlePageDisappearing();
|
||||
}
|
||||
|
||||
public override void ViewDidLoad()
|
||||
|
@ -276,10 +276,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
Element.PropertyChanged -= OnHandlePropertyChanged;
|
||||
Platform.SetRenderer(Element, null);
|
||||
if (_appeared)
|
||||
Page.SendDisappearing();
|
||||
|
||||
_appeared = false;
|
||||
_pageLifecycleManager?.Dispose();
|
||||
_pageLifecycleManager = null;
|
||||
|
||||
if (_events != null)
|
||||
{
|
||||
|
|
|
@ -115,7 +115,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateFont();
|
||||
UpdatePicker();
|
||||
UpdateTextColor();
|
||||
UpdateCharacterSpacing();
|
||||
UpdateHorizontalTextAlignment();
|
||||
UpdateVerticalTextAlignment();
|
||||
|
||||
|
@ -135,12 +134,10 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
if (e.PropertyName == Picker.TitleProperty.PropertyName || e.PropertyName == Picker.TitleColorProperty.PropertyName)
|
||||
{
|
||||
UpdatePicker();
|
||||
UpdateCharacterSpacing();
|
||||
}
|
||||
else if (e.PropertyName == Picker.SelectedIndexProperty.PropertyName)
|
||||
{
|
||||
UpdatePicker();
|
||||
UpdateCharacterSpacing();
|
||||
}
|
||||
else if (e.PropertyName == Picker.CharacterSpacingProperty.PropertyName)
|
||||
UpdateCharacterSpacing();
|
||||
|
@ -183,7 +180,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
void RowsCollectionChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdatePicker();
|
||||
UpdateCharacterSpacing();
|
||||
}
|
||||
|
||||
protected void UpdateCharacterSpacing()
|
||||
|
|
|
@ -351,7 +351,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
if (panGestureRecognizer != null)
|
||||
{
|
||||
var point = panGestureRecognizer.LocationInView(Control);
|
||||
CGPoint point = panGestureRecognizer.LocationInView(this);
|
||||
var navigationController = GetUINavigationController(GetViewController());
|
||||
|
||||
switch (panGestureRecognizer.State)
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
bool? _defaultBarTranslucent;
|
||||
bool _loaded;
|
||||
Size _queuedSize;
|
||||
PageLifecycleManager _pageLifecycleManager;
|
||||
|
||||
Page Page => Element as Page;
|
||||
|
||||
|
@ -72,6 +73,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
|
||||
|
||||
_pageLifecycleManager = new PageLifecycleManager(Element as IPageController);
|
||||
|
||||
OnPagesChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
|
||||
if (element != null)
|
||||
|
@ -110,14 +113,15 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
public override void ViewDidAppear(bool animated)
|
||||
{
|
||||
Page.SendAppearing();
|
||||
_pageLifecycleManager?.HandlePageAppearing();
|
||||
base.ViewDidAppear(animated);
|
||||
}
|
||||
|
||||
public override void ViewDidDisappear(bool animated)
|
||||
{
|
||||
base.ViewDidDisappear(animated);
|
||||
Page.SendDisappearing();
|
||||
_pageLifecycleManager?.HandlePageDisappearing();
|
||||
|
||||
}
|
||||
|
||||
public override void ViewDidLayoutSubviews()
|
||||
|
@ -152,7 +156,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
Page.SendDisappearing();
|
||||
_pageLifecycleManager?.Dispose();
|
||||
_pageLifecycleManager = null;
|
||||
Tabbed.PropertyChanged -= OnPropertyChanged;
|
||||
Tabbed.PagesChanged -= OnPagesChanged;
|
||||
FinishedCustomizingViewControllers -= HandleFinishedCustomizingViewControllers;
|
||||
|
|
|
@ -452,19 +452,19 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
hasClipShapeLayer =
|
||||
uiview.Layer != null &&
|
||||
uiview.Layer.Mask != null &&
|
||||
uiview.Layer.Mask.Name.Equals(ClipShapeLayer);
|
||||
uiview.Layer.Mask.Name == ClipShapeLayer;
|
||||
else
|
||||
{
|
||||
hasClipShapeLayer =
|
||||
uiview.MaskView != null &&
|
||||
uiview.MaskView.Layer.Mask != null &&
|
||||
uiview.MaskView.Layer.Mask.Name.Equals(ClipShapeLayer);
|
||||
uiview.MaskView.Layer.Mask.Name == ClipShapeLayer;
|
||||
}
|
||||
#else
|
||||
hasClipShapeLayer =
|
||||
uiview.Layer != null &&
|
||||
uiview.Layer.Mask != null &&
|
||||
uiview.Layer.Mask.Name.Equals(ClipShapeLayer);
|
||||
uiview.Layer.Mask.Name == ClipShapeLayer;
|
||||
#endif
|
||||
|
||||
var formsGeometry = element.Clip;
|
||||
|
|
|
@ -182,6 +182,7 @@
|
|||
<Compile Include="IOSDeviceInfo.cs" />
|
||||
<Compile Include="LinkerSafeAttribute.cs" />
|
||||
<Compile Include="ModalWrapper.cs" />
|
||||
<Compile Include="PageLifecycleManager.cs" />
|
||||
<Compile Include="Renderers\FormsCAKeyFrameAnimation.cs" />
|
||||
<Compile Include="Renderers\FormsCheckBox.cs" />
|
||||
<Compile Include="Renderers\FormsUIImageView.cs" />
|
||||
|
@ -336,7 +337,5 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Condition="'$(CI)' == 'true'" Include="Xamarin.Build.TypeRedirector" Version="0.1.2-preview" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Shapes\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup />
|
||||
</Project>
|
|
@ -14,11 +14,11 @@ variables:
|
|||
- name: BuildVersion44
|
||||
value: $[counter('xf-nuget-counter', 992000)]
|
||||
- name: NUGET_VERSION
|
||||
value: 5.4.0
|
||||
value: 5.6.0
|
||||
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
|
||||
value: true
|
||||
- name: DOTNET_VERSION
|
||||
value: 3.1.100
|
||||
value: 3.1.301
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
|
@ -64,7 +64,7 @@ stages:
|
|||
workspace:
|
||||
clean: all
|
||||
displayName: Build Windows Phase
|
||||
timeoutInMinutes: 120
|
||||
timeoutInMinutes: 60
|
||||
pool:
|
||||
name: $(vs2019VmPool)
|
||||
vmImage: $(vs2019VmImage)
|
||||
|
@ -128,8 +128,8 @@ stages:
|
|||
condition: ne(variables['vs2019VmPool'], 'Azure Pipelines')
|
||||
workspace:
|
||||
clean: all
|
||||
displayName: Build Windows Phase
|
||||
timeoutInMinutes: 120
|
||||
displayName: Build Windows Phase Bots
|
||||
timeoutInMinutes: 60
|
||||
pool:
|
||||
name: $(vs2019VmPool)
|
||||
vmImage: $(vs2019VmImage)
|
||||
|
@ -277,6 +277,32 @@ stages:
|
|||
steps:
|
||||
- template: build/steps/build-osx.yml
|
||||
|
||||
# My purpose is to enable quick testing of UI Tests when we need to debug
|
||||
# why tests are failing. Full test suite runs as part of release
|
||||
- stage: windows_tests
|
||||
displayName: Run Windows Tests
|
||||
condition: 'false'
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- job: win_hosted_tests
|
||||
workspace:
|
||||
clean: all
|
||||
displayName: Run UWP Tests
|
||||
timeoutInMinutes: 500
|
||||
pool:
|
||||
name: 'Azure Pipelines'
|
||||
vmImage: 'windows-2019'
|
||||
demands:
|
||||
msbuild
|
||||
strategy:
|
||||
matrix:
|
||||
debug:
|
||||
BuildConfiguration: 'Debug'
|
||||
steps:
|
||||
- template: build/steps/run-windows-tests.yml
|
||||
parameters:
|
||||
provisionatorPath : 'build/provisioning/provisioning.csx'
|
||||
|
||||
# only sign using the private server
|
||||
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
|
||||
- stage: nuget_signing
|
||||
|
|
250
build.cake
250
build.cake
|
@ -48,8 +48,12 @@ var IOS_TEST_LIBRARY = Argument("IOS_TEST_LIBRARY", $"./Xamarin.Forms.Core.iOS.U
|
|||
var IOS_IPA_PATH = Argument("IOS_IPA_PATH", $"./Xamarin.Forms.ControlGallery.iOS/bin/iPhoneSimulator/{configuration}/XamarinFormsControlGalleryiOS.app");
|
||||
var IOS_BUNDLE_ID = "com.xamarin.quickui.controlgallery";
|
||||
var IOS_BUILD_IPA = Argument("IOS_BUILD_IPA", (target == "cg-ios-deploy") ? true : (false || isCIBuild) );
|
||||
var NUNIT_TEST_WHERE = Argument("NUNIT_TEST_WHERE", "cat == Issues && cat != ManualReview");
|
||||
|
||||
var UWP_PACKAGE_ID = "0d4424f6-1e29-4476-ac00-ba22c3789cb6";
|
||||
var UWP_TEST_LIBRARY = GetBuildVariable("UWP_TEST_LIBRARY", $"./Xamarin.Forms.Core.Windows.UITests/bin/{configuration}/Xamarin.Forms.Core.Windows.UITests.dll");
|
||||
var UWP_PFX_PATH = Argument("UWP_PFX_PATH", "Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx");
|
||||
var UWP_APP_PACKAGES_PATH = Argument("UWP_APP_PACKAGES_PATH", "*/AppPackages/");
|
||||
var UWP_APP_DRIVER_INSTALL_PATH = Argument("UWP_APP_DRIVER_INSTALL_PATH", "https://github.com/microsoft/WinAppDriver/releases/download/v1.2-RC/WindowsApplicationDriver.msi");
|
||||
var ANDROID_RENDERERS = Argument("ANDROID_RENDERERS", "FAST");
|
||||
var XamarinFormsVersion = Argument("XamarinFormsVersion", "");
|
||||
var packageVersion = Argument("packageVersion", "");
|
||||
|
@ -57,7 +61,41 @@ var releaseChannelArg = Argument("CHANNEL", "Stable");
|
|||
releaseChannelArg = EnvironmentVariable("CHANNEL") ?? releaseChannelArg;
|
||||
var teamProject = Argument("TeamProject", "");
|
||||
bool buildForVS2017 = Convert.ToBoolean(Argument("buildForVS2017", "false"));
|
||||
bool isHostedAgent = agentName.StartsWith("Azure Pipelines");
|
||||
bool isHostedAgent = agentName.StartsWith("Azure Pipelines") || agentName.StartsWith("Hosted Agent");
|
||||
|
||||
|
||||
var NUNIT_TEST_WHERE = Argument("NUNIT_TEST_WHERE", "cat != Shell && cat != CollectionView && cat != UwpIgnore && cat != CarouselView");
|
||||
var ExcludeCategory = GetBuildVariable("ExcludeCategory", "")?.Replace("\"", "");
|
||||
var ExcludeCategory2 = GetBuildVariable("ExcludeCategory2", "")?.Replace("\"", "");
|
||||
var IncludeCategory = GetBuildVariable("IncludeCategory", "")?.Replace("\"", "");
|
||||
|
||||
// Replace Azure devops syntax for unit tests to Nunit3 filters
|
||||
if(!String.IsNullOrWhiteSpace(ExcludeCategory))
|
||||
{
|
||||
ExcludeCategory = String.Join(" && cat != ", ExcludeCategory.Split(new string[] { "--exclude-category" }, StringSplitOptions.None));
|
||||
if(!ExcludeCategory.StartsWith("cat"))
|
||||
ExcludeCategory = $" cat != {ExcludeCategory}";
|
||||
|
||||
NUNIT_TEST_WHERE = $"{NUNIT_TEST_WHERE} && {ExcludeCategory}";
|
||||
}
|
||||
|
||||
if(!String.IsNullOrWhiteSpace(ExcludeCategory2))
|
||||
{
|
||||
ExcludeCategory2 = String.Join(" && cat != ", ExcludeCategory2.Split(new string[] { "--exclude-category" }, StringSplitOptions.None));
|
||||
if(!ExcludeCategory2.StartsWith("cat"))
|
||||
ExcludeCategory2 = $" cat != {ExcludeCategory2}";
|
||||
|
||||
NUNIT_TEST_WHERE = $"{NUNIT_TEST_WHERE} && {ExcludeCategory2}";
|
||||
}
|
||||
|
||||
if(!String.IsNullOrWhiteSpace(IncludeCategory))
|
||||
{
|
||||
IncludeCategory = String.Join(" || cat == ", IncludeCategory.Split(new string[] { "--include-category" }, StringSplitOptions.None));
|
||||
if(!IncludeCategory.StartsWith("cat"))
|
||||
IncludeCategory = $" cat == {IncludeCategory}";
|
||||
|
||||
NUNIT_TEST_WHERE = $"({NUNIT_TEST_WHERE}) && ({IncludeCategory})";
|
||||
}
|
||||
|
||||
var ANDROID_HOME = EnvironmentVariable("ANDROID_HOME") ??
|
||||
(IsRunningOnWindows () ? "C:\\Program Files (x86)\\Android\\android-sdk\\" : "");
|
||||
|
@ -404,30 +442,129 @@ Task("provision-netsdk-local")
|
|||
}
|
||||
});
|
||||
|
||||
Task ("cg-uwp")
|
||||
.IsDependentOn("BuildTasks")
|
||||
.Does (() =>
|
||||
{
|
||||
MSBuild ("Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal.csproj",
|
||||
GetMSBuildSettings().WithRestore());
|
||||
});
|
||||
|
||||
Task ("cg-uwp-build-tests")
|
||||
.IsDependentOn("BuildTasks")
|
||||
.Does (() =>
|
||||
{
|
||||
MSBuild ("Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal.csproj",
|
||||
GetMSBuildSettings(null)
|
||||
.WithProperty("AppxBundlePlatforms", "x86")
|
||||
.WithProperty("AppxBundle", "Always")
|
||||
.WithProperty("UapAppxPackageBuildMode", "StoreUpload")
|
||||
.WithProperty("AppxPackageSigningEnabled", "true")
|
||||
.WithProperty("PackageCertificateThumbprint", "a59087cc92a9a8117ffdb5255eaa155748f9f852")
|
||||
.WithProperty("PackageCertificateKeyFile", "Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx")
|
||||
.WithProperty("PackageCertificatePassword", "")
|
||||
.WithRestore()
|
||||
);
|
||||
|
||||
MSBuild("Xamarin.Forms.Core.Windows.UITests\\Xamarin.Forms.Core.Windows.UITests.csproj",
|
||||
GetMSBuildSettings().WithRestore());
|
||||
});
|
||||
|
||||
Task ("cg-uwp-deploy")
|
||||
.WithCriteria(IsRunningOnWindows())
|
||||
.Does (() =>
|
||||
{
|
||||
var uninstallPS = new Action (() => {
|
||||
try {
|
||||
StartProcess ("powershell",
|
||||
"$app = Get-AppxPackage -Name " + UWP_PACKAGE_ID + "; if ($app) { Remove-AppxPackage -Package $app.PackageFullName }");
|
||||
} catch { }
|
||||
});
|
||||
// Try to uninstall the app if it exists from before
|
||||
uninstallPS();
|
||||
|
||||
StartProcess("certutil", "-f -p \"\" -importpfx \"" + UWP_PFX_PATH + "\"");
|
||||
|
||||
// Install the appx
|
||||
var dependencies = GetFiles(UWP_APP_PACKAGES_PATH + "*/Dependencies/x86/*.appx");
|
||||
|
||||
foreach (var dep in dependencies) {
|
||||
try
|
||||
{
|
||||
Information("Installing Dependency appx: {0}", dep);
|
||||
StartProcess("powershell", "Add-AppxPackage -Path \"" + MakeAbsolute(dep).FullPath + "\"");
|
||||
}
|
||||
catch(Exception exc)
|
||||
{
|
||||
Information("Error: {0}", exc);
|
||||
}
|
||||
}
|
||||
|
||||
var appxBundlePath = GetFiles(UWP_APP_PACKAGES_PATH + "*/*.appxbundle").First ();
|
||||
Information("Installing appx: {0}", appxBundlePath);
|
||||
StartProcess ("powershell", "Add-AppxPackage -Path \"" + MakeAbsolute(appxBundlePath).FullPath + "\"");
|
||||
});
|
||||
|
||||
Task("cg-uwp-run-tests")
|
||||
.IsDependentOn("provision-uitests-uwp")
|
||||
.Does(() =>
|
||||
{
|
||||
System.Diagnostics.Process process = null;
|
||||
if(!isHostedAgent)
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = new System.Diagnostics.ProcessStartInfo(@"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe")
|
||||
{
|
||||
};
|
||||
|
||||
process = System.Diagnostics.Process.Start(info);
|
||||
}
|
||||
catch(Exception exc)
|
||||
{
|
||||
Information("Failed: {0}", exc);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NUnit3(new [] { UWP_TEST_LIBRARY },
|
||||
new NUnit3Settings {
|
||||
Params = new Dictionary<string, string>()
|
||||
{
|
||||
},
|
||||
Where = NUNIT_TEST_WHERE
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
process?.Kill();
|
||||
}
|
||||
catch{}
|
||||
}
|
||||
});
|
||||
|
||||
Task("cg-uwp-run-tests-ci")
|
||||
.IsDependentOn("provision-windowssdk")
|
||||
.IsDependentOn("cg-uwp-deploy")
|
||||
.IsDependentOn("cg-uwp-run-tests")
|
||||
.Does(() =>
|
||||
{
|
||||
});
|
||||
|
||||
Task("provision-uitests-uwp")
|
||||
.WithCriteria(IsRunningOnWindows() && !isHostedAgent)
|
||||
.Description("Installs and Starts WindowsApplicationDriver. Use WinAppDriverPath to specify WinAppDriver Location.")
|
||||
.Does(() =>
|
||||
{
|
||||
if(IsRunningOnWindows())
|
||||
string installPath = Argument("WinAppDriverPath", @"C:\Program Files (x86)\");
|
||||
string driverPath = System.IO.Path.Combine(installPath, "Windows Application Driver");
|
||||
if(!DirectoryExists(driverPath))
|
||||
{
|
||||
string installPath = Argument("WinAppDriverPath", @"C:\Program Files (x86)\");
|
||||
string driverPath = System.IO.Path.Combine(installPath, "Windows Application Driver");
|
||||
if(!DirectoryExists(driverPath))
|
||||
{
|
||||
InstallMsi("https://github.com/microsoft/WinAppDriver/releases/download/v1.2-RC/WindowsApplicationDriver.msi", installPath);
|
||||
}
|
||||
|
||||
|
||||
var info = new System.Diagnostics.ProcessStartInfo
|
||||
{
|
||||
FileName = "WinAppDriver",
|
||||
WorkingDirectory = driverPath
|
||||
};
|
||||
|
||||
Information("Starting: {0}", driverPath);
|
||||
System.Diagnostics.Process.Start(info);
|
||||
InstallMsi(UWP_APP_DRIVER_INSTALL_PATH, installPath);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
void InstallMsi(string msiFile, string installTo, string fileName = "InstallFile.msi")
|
||||
|
@ -550,21 +687,81 @@ Task("WriteGoogleMapsAPIKey")
|
|||
});
|
||||
|
||||
Task("BuildForNuget")
|
||||
.IsDependentOn("BuildTasks")
|
||||
.Description("Builds all necessary projects to create Nuget Packages")
|
||||
.Does(() =>
|
||||
{
|
||||
try{
|
||||
try
|
||||
{
|
||||
|
||||
var msbuildSettings = GetMSBuildSettings();
|
||||
var binaryLogger = new MSBuildBinaryLogSettings {
|
||||
Enabled = true
|
||||
Enabled = isCIBuild
|
||||
};
|
||||
|
||||
msbuildSettings.BinaryLogger = binaryLogger;
|
||||
binaryLogger.FileName = $"{artifactStagingDirectory}/win-{configuration}.binlog";
|
||||
|
||||
MSBuild("./Xamarin.Forms.sln", msbuildSettings);
|
||||
|
||||
// // This currently fails on CI will revisit later
|
||||
// if(isCIBuild)
|
||||
// {
|
||||
// MSBuild("./Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj", GetMSBuildSettings().WithTarget("Restore"));
|
||||
// MSBuild("./Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj", GetMSBuildSettings());
|
||||
// }
|
||||
|
||||
// MSBuild("./Xamarin.Forms.sln", GetMSBuildSettings().WithTarget("Restore"));
|
||||
// MSBuild("./Xamarin.Forms.DualScreen.sln", GetMSBuildSettings().WithTarget("Restore"));
|
||||
|
||||
// if(isCIBuild)
|
||||
// {
|
||||
// foreach(var platformProject in GetFiles("./Xamarin.*.UnitTests/*.csproj").Select(x=> x.FullPath))
|
||||
// {
|
||||
// if(platformProject.Contains("Xamarin.Forms.Xaml.UnitTests"))
|
||||
// continue;
|
||||
|
||||
// Information("Building: {0}", platformProject);
|
||||
// MSBuild(platformProject,
|
||||
// GetMSBuildSettings().WithRestore());
|
||||
// }
|
||||
// }
|
||||
|
||||
// MSBuild("./Xamarin.Forms.sln", GetMSBuildSettings().WithTarget("Restore"));
|
||||
// MSBuild("./Xamarin.Forms.DualScreen.sln", GetMSBuildSettings().WithTarget("Restore"));
|
||||
|
||||
// msbuildSettings.BinaryLogger = binaryLogger;
|
||||
|
||||
// var platformProjects =
|
||||
// GetFiles("./Xamarin.Forms.Platform.*/*.csproj")
|
||||
// .Union(GetFiles("./Stubs/*/*.csproj"))
|
||||
// .Union(GetFiles("./Xamarin.Forms.Maps.*/*.csproj"))
|
||||
// .Union(GetFiles("./Xamarin.Forms.Pages.*/*.csproj"))
|
||||
// .Union(GetFiles("./Xamarin.Forms.Material.*/*.csproj"))
|
||||
// .Union(GetFiles("./Xamarin.Forms.Core.Design/*.csproj"))
|
||||
// .Union(GetFiles("./Xamarin.Forms.Xaml.Design/*.csproj"))
|
||||
// .Select(x=> x.FullPath).Distinct()
|
||||
// .ToList();
|
||||
|
||||
// foreach(var platformProject in platformProjects)
|
||||
// {
|
||||
// if(platformProject.Contains("UnitTests"))
|
||||
// continue;
|
||||
|
||||
// msbuildSettings = GetMSBuildSettings();
|
||||
// string projectName = platformProject
|
||||
// .Replace(' ', '_')
|
||||
// .Split('/')
|
||||
// .Last();
|
||||
|
||||
// binaryLogger.FileName = $"{artifactStagingDirectory}/{projectName}-{configuration}.binlog";
|
||||
// msbuildSettings.BinaryLogger = binaryLogger;
|
||||
|
||||
// Information("Building: {0}", platformProject);
|
||||
// MSBuild(platformProject,
|
||||
// msbuildSettings);
|
||||
// }
|
||||
|
||||
// dual screen
|
||||
msbuildSettings = GetMSBuildSettings();
|
||||
msbuildSettings.BinaryLogger = binaryLogger;
|
||||
binaryLogger.FileName = $"{artifactStagingDirectory}/dualscreen-{configuration}-csproj.binlog";
|
||||
|
@ -842,6 +1039,11 @@ Task("Default")
|
|||
|
||||
RunTarget(target);
|
||||
|
||||
T GetBuildVariable<T>(string key, T defaultValue)
|
||||
{
|
||||
return Argument(key, EnvironmentVariable(key, defaultValue));
|
||||
}
|
||||
|
||||
void StartVisualStudio(string sln = "Xamarin.Forms.sln")
|
||||
{
|
||||
if(isCIBuild)
|
||||
|
@ -903,4 +1105,4 @@ AppleSimulator GetIosSimulator()
|
|||
// Look for a matching simulator on the system
|
||||
var sim = sims.First (s => s.Name == IOS_SIM_NAME && s.Runtime == IOS_SIM_RUNTIME);
|
||||
return sim;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ parameters:
|
|||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
||||
- script: build.cmd -Target provision
|
||||
displayName: 'Cake Provision'
|
||||
condition: eq(variables['provisioningCake'], 'true')
|
||||
|
@ -190,6 +191,49 @@ steps:
|
|||
**/*.binlog
|
||||
|
||||
TargetFolder: ${{ parameters.artifactsTargetFolder }}
|
||||
|
||||
- script: build.cmd -Target cg-uwp-build-tests -ScriptArgs '-BUILD_CONFIGURATION="$(BuildConfiguration)"'
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
displayName: 'Build Tests and APPX'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Appx Packages'
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
inputs:
|
||||
Contents: |
|
||||
Xamarin.Forms.ControlGallery.WindowsUniversal/AppPackages/*/*
|
||||
Xamarin.Forms.ControlGallery.WindowsUniversal/AppPackages/*/Add-AppDevPackage.resources/**
|
||||
Xamarin.Forms.ControlGallery.WindowsUniversal/AppPackages/*/TelemetryDependencies/**
|
||||
Xamarin.Forms.ControlGallery.WindowsUniversal/AppPackages/*/Dependencies/x86/**
|
||||
TargetFolder: '$(build.artifactstagingdirectory)'
|
||||
CleanTargetFolder: false
|
||||
flattenFolders: false
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Cake File'
|
||||
inputs:
|
||||
Contents: |
|
||||
build.cake
|
||||
TargetFolder: '${{ parameters.artifactsTargetFolder }}'
|
||||
CleanTargetFolder: false
|
||||
flattenFolders: false
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy UITest Files'
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
inputs:
|
||||
SourceFolder: Xamarin.Forms.Core.Windows.UITests/bin/$(BuildConfiguration)/
|
||||
TargetFolder: '$(build.artifactstagingdirectory)/UITests'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Certificate File'
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
inputs:
|
||||
Contents: |
|
||||
Xamarin.Forms.ControlGallery.WindowsUniversal\Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx
|
||||
TargetFolder: '$(build.artifactstagingdirectory)'
|
||||
CleanTargetFolder: false
|
||||
flattenFolders: false
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Pages Files dlls'
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
parameters:
|
||||
name: '' # in the form type_platform_host
|
||||
targetFolder: '' # the bootstrapper target
|
||||
preBuildSteps: [] # any steps to run before the build
|
||||
postBuildSteps: [] # any additional steps to run after the build
|
||||
slnPath : 'Xamarin.Forms.sln'
|
||||
csprojPath : 'Xamarin.Forms.Platform.UAP\Xamarin.Forms.Platform.UAP.csproj'
|
||||
msbuildExtraArguments : ''
|
||||
artifactsTargetFolder: '$(build.artifactstagingdirectory)'
|
||||
artifactsName: 'win_build'
|
||||
nunitTestAdapterFolder: 'packages/NUnitTestAdapter.AnyVersion/build/'
|
||||
nunitTestFolder: '$(build.sourcesdirectory)'
|
||||
includeUwp: 'true'
|
||||
includeAndroid: 'true'
|
||||
includeNonUwpAndNonAndroid: 'true'
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Install Cake'
|
||||
inputs:
|
||||
command: custom
|
||||
custom: tool
|
||||
arguments: 'update cake.tool -g'
|
||||
|
||||
- script: build.cmd -Target provision
|
||||
displayName: 'Cake Provision'
|
||||
condition: eq(variables['provisioningCake'], 'true')
|
||||
|
||||
- task: xamops.azdevex.provisionator-task.provisionator@1
|
||||
displayName: 'Provisionator'
|
||||
condition: eq(variables['provisioning'], 'true')
|
||||
inputs:
|
||||
provisioning_script: ${{ parameters.provisionatorPath }}
|
||||
provisioning_extra_args: ${{ parameters.provisionator.extraArguments }}
|
||||
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: 'Use NuGet $(NUGET_VERSION)'
|
||||
condition: ne(variables['NUGET_VERSION'], '')
|
||||
inputs:
|
||||
versionSpec: $(NUGET_VERSION)
|
||||
|
||||
- script: build.cmd -Target cg-uwp-build-tests -ScriptArgs '-BUILD_CONFIGURATION="$(BuildConfiguration)"'
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
displayName: 'Build Tests and APPX'
|
||||
|
||||
- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
displayName: 'Start - WinAppDriver'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run UI Tests'
|
||||
condition: eq(variables['BuildConfiguration'], 'Debug')
|
||||
inputs:
|
||||
command: custom
|
||||
custom: cake
|
||||
arguments: ' --target=cg-uwp-run-tests-ci --verbosity=diagnostic --NUNIT_TEST_WHERE="method == Issue2Test || method == Issue1Test || method == Bugzilla29128Test"'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TestResult.xml'
|
||||
inputs:
|
||||
testResultsFormat: NUnit
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
condition: always()
|
||||
|
||||
- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
|
||||
displayName: 'Stop - WinAppDriver'
|
||||
inputs:
|
||||
OperationType: Stop
|
||||
condition: always()
|
Загрузка…
Ссылка в новой задаче