This commit is contained in:
Rui Marinho 2018-05-15 16:16:52 +01:00
Родитель 9791291284 6beff058da
Коммит c22b8b9e0f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 924E81B5DB553385
13 изменённых файлов: 230 добавлений и 25 удалений

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

@ -0,0 +1,43 @@
<?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.Issue2625">
<ContentPage.Content>
<StackLayout>
<Label Text="The buttons below should have their background colors set by the VisualStateManager. If they have the default button background color, this test has failed."></Label>
<Button
HorizontalOptions="Center"
Text="I should have a Lime background"
VerticalOptions="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
<Button
HorizontalOptions="Center"
Text="I should have a Pink background"
IsEnabled="False"
VerticalOptions="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>

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

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Xaml;
namespace Xamarin.Forms.Controls.Issues
{
#if APP
[XamlCompilation(XamlCompilationOptions.Compile)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 2625, "VisualStateManager attached to Button seems to not work on Android", PlatformAffected.Android)]
public partial class Issue2625 : ContentPage
{
public Issue2625 ()
{
#if APP
InitializeComponent ();
#endif
}
}
}

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

@ -307,6 +307,10 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue1672.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2394.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2595.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2625.xaml.cs">
<DependentUpon>Issue2625.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue2983.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2963.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2981.cs" />
@ -891,4 +895,10 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue2625.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

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

@ -76,6 +76,12 @@ namespace Xamarin.Forms.Controls
map.MoveToRegion (MapSpan.FromCenterAndRadius (new Position (41.890202, 12.492049), Distance.FromMiles (0.5)));
};
var buttonRemove = new Button { Text = "Remove Pin" };
buttonRemove.Clicked += (a, e) =>
{
map.Pins.RemoveAt(0);
};
_stack = new StackLayout {
Spacing = 0,
Padding = new Thickness (30, 0)
@ -114,7 +120,8 @@ namespace Xamarin.Forms.Controls
_stack.Children.Add (buttonAddressFromPosition);
_stack.Children.Add (buttonHome);
_stack.Children.Add (buttonZoomPin);
_stack.Children.Add(buttonEditPin);
_stack.Children.Add (buttonEditPin);
_stack.Children.Add (buttonRemove);
Content = _stack;
}
@ -159,7 +166,7 @@ namespace Xamarin.Forms.Controls
{
Pin pin = (Pin)sender;
Application.Current.MainPage.DisplayAlert("Pin Click",
$"You clicked the {pin.Label} pin, located at {pin.Address}, or coordinates ({pin.Position.Latitude}, {pin.Position.Longitude})",
$"You clicked the {pin.Label} pin, located at {pin.Address}, or coordinates ({pin.Position.Latitude}, {pin.Position.Longitude})",
"OK");
}
}

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

@ -212,5 +212,55 @@ namespace Xamarin.Forms.Core.UnitTests
Assert.That(groups1[0].CurrentState.Name, Is.EqualTo(NormalStateName));
}
[Test]
public void VisualElementGoesToCorrectStateWhenAvailable()
{
var label = new Label();
double targetBottomMargin = 1.5;
var group = new VisualStateGroup();
var list = new VisualStateGroupList();
var normalState = new VisualState { Name = NormalStateName };
normalState.Setters.Add(new Setter { Property = View.MarginBottomProperty, Value = targetBottomMargin });
list.Add(group);
group.States.Add(normalState);
VisualStateManager.SetVisualStateGroups(label, list);
Assert.That(label.Margin.Bottom, Is.EqualTo(targetBottomMargin));
}
[Test]
public void VisualElementGoesToCorrectStateWhenAvailableFromSetter()
{
double targetBottomMargin = 1.5;
var group = new VisualStateGroup();
var list = new VisualStateGroupList();
var normalState = new VisualState { Name = NormalStateName };
normalState.Setters.Add(new Setter { Property = View.MarginBottomProperty, Value = targetBottomMargin });
var x = new Setter
{
Property = VisualStateManager.VisualStateGroupsProperty,
Value = list
};
list.Add(group);
group.States.Add(normalState);
var label1 = new Label();
var label2 = new Label();
x.Apply(label1);
x.Apply(label2);
Assert.That(label1.Margin.Bottom, Is.EqualTo(targetBottomMargin));
Assert.That(label2.Margin.Bottom, Is.EqualTo(targetBottomMargin));
}
}
}

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

@ -19,11 +19,20 @@ namespace Xamarin.Forms
public static readonly BindableProperty VisualStateGroupsProperty =
BindableProperty.CreateAttached("VisualStateGroups", typeof(VisualStateGroupList), typeof(VisualElement),
defaultValue: null, propertyChanged: VisualStateGroupsPropertyChanged,
defaultValueCreator: bindable => new VisualStateGroupList());
defaultValueCreator: bindable => new VisualStateGroupList {VisualElement = (VisualElement)bindable});
static void VisualStateGroupsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
GoToState((VisualElement)bindable, CommonStates.Normal);
if (oldValue is VisualStateGroupList oldVisualStateGroupList)
{
oldVisualStateGroupList.VisualElement = null;
}
var visualElement = (VisualElement)bindable;
((VisualStateGroupList)newValue).VisualElement = visualElement;
visualElement.ChangeVisualState();
}
public static IList<VisualStateGroup> GetVisualStateGroups(VisualElement visualElement)
@ -94,7 +103,7 @@ namespace Xamarin.Forms
{
readonly IList<VisualStateGroup> _internalList;
void Validate(IList<VisualStateGroup> groups)
static void Validate(IList<VisualStateGroup> groups)
{
// If we have 1 group, no need to worry about duplicate group names
if (groups.Count > 1)
@ -118,12 +127,18 @@ namespace Xamarin.Forms
public VisualStateGroupList()
{
_internalList = new WatchAddList<VisualStateGroup>(Validate);
_internalList = new WatchAddList<VisualStateGroup>(ValidateAndNotify);
}
void ValidateOnStatesChanged(object sender, EventArgs eventArgs)
void ValidateAndNotify(object sender, EventArgs eventArgs)
{
Validate(_internalList);
ValidateAndNotify(_internalList);
}
void ValidateAndNotify(IList<VisualStateGroup> groups)
{
Validate(groups);
OnStatesChanged();
}
public IEnumerator<VisualStateGroup> GetEnumerator()
@ -139,14 +154,14 @@ namespace Xamarin.Forms
public void Add(VisualStateGroup item)
{
_internalList.Add(item);
item.StatesChanged += ValidateOnStatesChanged;
item.StatesChanged += ValidateAndNotify;
}
public void Clear()
{
foreach (var group in _internalList)
{
group.StatesChanged -= ValidateOnStatesChanged;
group.StatesChanged -= ValidateAndNotify;
}
_internalList.Clear();
@ -164,7 +179,7 @@ namespace Xamarin.Forms
public bool Remove(VisualStateGroup item)
{
item.StatesChanged -= ValidateOnStatesChanged;
item.StatesChanged -= ValidateAndNotify;
return _internalList.Remove(item);
}
@ -179,13 +194,13 @@ namespace Xamarin.Forms
public void Insert(int index, VisualStateGroup item)
{
item.StatesChanged += ValidateOnStatesChanged;
item.StatesChanged += ValidateAndNotify;
_internalList.Insert(index, item);
}
public void RemoveAt(int index)
{
_internalList[index].StatesChanged -= ValidateOnStatesChanged;
_internalList[index].StatesChanged -= ValidateAndNotify;
_internalList.RemoveAt(index);
}
@ -194,6 +209,13 @@ namespace Xamarin.Forms
get => _internalList[index];
set => _internalList[index] = value;
}
internal VisualElement VisualElement { get; set; }
void OnStatesChanged()
{
VisualElement?.ChangeVisualState();
}
}
[RuntimeNameProperty(nameof(Name))]

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

@ -16,7 +16,7 @@ using Math = System.Math;
namespace Xamarin.Forms.Maps.Android
{
public class MapRenderer : ViewRenderer<Map, MapView>, GoogleMap.IOnCameraMoveListener, IOnMapReadyCallback
public class MapRenderer : ViewRenderer<Map, MapView>, GoogleMap.IOnCameraMoveListener, IOnMapReadyCallback
{
const string MoveMessageName = "MapMoveToRegion";
@ -192,31 +192,31 @@ namespace Xamarin.Forms.Maps.Android
MoveToRegion(Element.LastMoveToRegion, false);
}
}
protected virtual void OnMapReady(GoogleMap map)
{
if (map == null)
{
return;
}
map.SetOnCameraMoveListener(this);
map.InfoWindowClick += MapOnMarkerClick;
map.UiSettings.ZoomControlsEnabled = Map.HasZoomEnabled;
map.UiSettings.ZoomGesturesEnabled = Map.HasZoomEnabled;
map.UiSettings.ScrollGesturesEnabled = Map.HasScrollEnabled;
map.MyLocationEnabled = map.UiSettings.MyLocationButtonEnabled = Map.IsShowingUser;
SetMapType();
}
protected virtual MarkerOptions CreateMarker(Pin pin)
{
var opts = new MarkerOptions();
opts.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
opts.SetTitle(pin.Label);
opts.SetSnippet(pin.Address);
return opts;
}
@ -290,7 +290,7 @@ namespace Xamarin.Forms.Maps.Android
break;
}
// only consider event handled if a handler is present.
// only consider event handled if a handler is present.
// Else allow default behavior of displaying an info window.
targetPin?.SendTap();
}
@ -373,8 +373,8 @@ namespace Xamarin.Forms.Maps.Android
foreach (Pin p in pins)
{
p.PropertyChanged -= PinOnPropertyChanged;
var marker = _markers.FirstOrDefault(m => m.Id == (string)p.Id);
var marker = _markers.FirstOrDefault(m => (object)m.Id == p.Id);
if (marker == null)
{
continue;

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

@ -247,7 +247,11 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
return;
Color borderColor = Element.BorderColor;
_backgroundDrawable.SetStroke(3, borderColor.IsDefault ? AColor.White : borderColor.ToAndroid());
if (borderColor.IsDefault)
_backgroundDrawable.SetStroke(0, AColor.Transparent);
else
_backgroundDrawable.SetStroke(3, borderColor.ToAndroid());
}
void UpdateShadow()

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

@ -349,6 +349,18 @@ namespace Xamarin.Forms.Platform.UWP
ScrollTo(listProxy.ProxiedEnumerable, listProxy[0], ScrollToPosition.Start, true, true);
}
bool ScrollToItemWithAnimation(ScrollViewer viewer, object item)
{
var selectorItem = List.ContainerFromItem(item) as Windows.UI.Xaml.Controls.Primitives.SelectorItem;
var transform = selectorItem?.TransformToVisual(viewer.Content as UIElement);
var position = transform?.TransformPoint(new Windows.Foundation.Point(0, 0));
if (!position.HasValue)
return false;
// scroll with animation
viewer.ChangeView(position.Value.X, position.Value.Y, null);
return true;
}
#pragma warning disable 1998 // considered for removal
async void ScrollTo(object group, object item, ScrollToPosition toPosition, bool shouldAnimate, bool includeGroup = false, bool previouslyFailed = false)
#pragma warning restore 1998
@ -375,6 +387,10 @@ namespace Xamarin.Forms.Platform.UWP
object[] t = templatedItems.GetGroup(location.Item1).ItemsSource.Cast<object>().ToArray();
object c = t[location.Item2];
// scroll to desired item with animation
if (shouldAnimate && ScrollToItemWithAnimation(viewer, c))
return;
double viewportHeight = viewer.ViewportHeight;
var semanticLocation = new SemanticZoomLocation { Item = c };

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

@ -96,8 +96,9 @@ namespace Xamarin.Forms.Platform.UWP
// 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
_queryTextBox.UseFormsVsm = Element.HasVisualStateGroups()
|| !Element.OnThisPlatform().GetIsLegacyColorModeEnabled();
if (_queryTextBox != null)
_queryTextBox.UseFormsVsm = Element.HasVisualStateGroups()
|| !Element.OnThisPlatform().GetIsLegacyColorModeEnabled();
}
void OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs e)

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

@ -48,9 +48,10 @@ using UIKit;
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CarouselPageRenderer))]
[assembly: ExportRenderer(typeof(Page), typeof(PageRenderer))]
[assembly: ExportRenderer(typeof(MasterDetailPage), typeof(PhoneMasterDetailRenderer), UIUserInterfaceIdiom.Phone)]
[assembly: ExportRenderer(typeof(MasterDetailPage), typeof(TabletMasterDetailRenderer), UIUserInterfaceIdiom.Pad)]
#endif
[assembly: ExportRenderer(typeof(MasterDetailPage), typeof(TabletMasterDetailRenderer), UIUserInterfaceIdiom.Pad)]
[assembly: ExportCell(typeof(Cell), typeof(CellRenderer))]
[assembly: ExportCell(typeof(ImageCell), typeof(ImageCellRenderer))]
[assembly: ExportCell(typeof(EntryCell), typeof(EntryCellRenderer))]

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

@ -113,6 +113,18 @@
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
<Entry x:Name="Button1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
</StackLayout>

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

@ -170,6 +170,17 @@ namespace Xamarin.Forms.Xaml.UnitTests
Assert.That(normal.Setters.Count, Is.EqualTo(0));
Assert.That(disabled.Setters.Count, Is.EqualTo(2));
}
[TestCase(false)]
[TestCase(true)]
public void VisualElementGoesToCorrectStateWhenAvailable(bool useCompiledXaml)
{
var layout = new VisualStateManagerTests(useCompiledXaml);
var button = layout.Button1;
Assert.That(button.BackgroundColor, Is.EqualTo(Color.Lime));
}
}
}
}