487 строки
13 KiB
C#
Executable File
487 строки
13 KiB
C#
Executable File
using System;
|
|
using System.Linq;
|
|
using System.ComponentModel;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using WSwipeBehaviorOnInvoked = Microsoft.UI.Xaml.Controls.SwipeBehaviorOnInvoked;
|
|
using WSwipeControl = Microsoft.UI.Xaml.Controls.SwipeControl;
|
|
using WSwipeItems = Microsoft.UI.Xaml.Controls.SwipeItems;
|
|
using WSwipeItem = Microsoft.UI.Xaml.Controls.SwipeItem;
|
|
using WSwipeMode = Microsoft.UI.Xaml.Controls.SwipeMode;
|
|
|
|
namespace Xamarin.Forms.Platform.UWP
|
|
{
|
|
public class SwipeViewRenderer : ViewRenderer<SwipeView, WSwipeControl>
|
|
{
|
|
bool _isDisposed;
|
|
Dictionary<WSwipeItem, SwipeItem> _leftItems;
|
|
Dictionary<WSwipeItem, SwipeItem> _rightItems;
|
|
Dictionary<WSwipeItem, SwipeItem> _topItems;
|
|
Dictionary<WSwipeItem, SwipeItem> _bottomItems;
|
|
|
|
public SwipeViewRenderer()
|
|
{
|
|
AutoPackage = false;
|
|
}
|
|
|
|
protected override void OnElementChanged(ElementChangedEventArgs<SwipeView> e)
|
|
{
|
|
base.OnElementChanged(e);
|
|
|
|
if (e.NewElement != null)
|
|
{
|
|
e.NewElement.CloseRequested += OnCloseRequested;
|
|
e.NewElement.LeftItems.CollectionChanged += OnSwipeItemsChanged;
|
|
e.NewElement.RightItems.CollectionChanged += OnSwipeItemsChanged;
|
|
e.NewElement.TopItems.CollectionChanged += OnSwipeItemsChanged;
|
|
e.NewElement.BottomItems.CollectionChanged += OnSwipeItemsChanged;
|
|
|
|
if (Control == null)
|
|
{
|
|
SetNativeControl(new WSwipeControl());
|
|
}
|
|
|
|
UpdateContent();
|
|
UpdateSwipeItems();
|
|
UpdateBackgroundColor();
|
|
}
|
|
|
|
if (e.OldElement != null)
|
|
{
|
|
e.OldElement.CloseRequested -= OnCloseRequested;
|
|
e.OldElement.LeftItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
e.OldElement.RightItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
e.OldElement.TopItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
e.OldElement.BottomItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
}
|
|
}
|
|
|
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs changedProperty)
|
|
{
|
|
base.OnElementPropertyChanged(sender, changedProperty);
|
|
|
|
if (changedProperty.PropertyName == ContentView.ContentProperty.PropertyName)
|
|
UpdateContent();
|
|
else if (changedProperty.IsOneOf(SwipeView.LeftItemsProperty, SwipeView.RightItemsProperty, SwipeView.TopItemsProperty, SwipeView.BottomItemsProperty))
|
|
UpdateSwipeItems();
|
|
else if (changedProperty.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
|
|
UpdateBackgroundColor();
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (_isDisposed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (disposing)
|
|
{
|
|
if (Element != null)
|
|
{
|
|
Element.CloseRequested -= OnCloseRequested;
|
|
|
|
if (Element.LeftItems != null)
|
|
{
|
|
Element.LeftItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
Element.LeftItems.PropertyChanged -= OnSwipeItemsPropertyChanged;
|
|
}
|
|
|
|
if (Element.RightItems != null)
|
|
{
|
|
Element.RightItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
Element.RightItems.PropertyChanged -= OnSwipeItemsPropertyChanged;
|
|
}
|
|
|
|
if (Element.TopItems != null)
|
|
{
|
|
Element.TopItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
Element.TopItems.PropertyChanged -= OnSwipeItemsPropertyChanged;
|
|
}
|
|
|
|
if (Element.BottomItems != null)
|
|
{
|
|
Element.BottomItems.CollectionChanged -= OnSwipeItemsChanged;
|
|
Element.BottomItems.PropertyChanged -= OnSwipeItemsPropertyChanged;
|
|
}
|
|
}
|
|
|
|
if (_leftItems != null)
|
|
DisposeSwipeItems(_leftItems);
|
|
|
|
if (_rightItems != null)
|
|
DisposeSwipeItems(_rightItems);
|
|
|
|
if (_topItems != null)
|
|
DisposeSwipeItems(_topItems);
|
|
|
|
if (_bottomItems != null)
|
|
DisposeSwipeItems(_bottomItems);
|
|
}
|
|
|
|
_isDisposed = true;
|
|
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
protected override void UpdateBackgroundColor()
|
|
{
|
|
Color backgroundColor = Element.BackgroundColor;
|
|
|
|
if (Control != null)
|
|
{
|
|
Control.Background = backgroundColor.IsDefault ? null : backgroundColor.ToBrush();
|
|
}
|
|
|
|
base.UpdateBackgroundColor();
|
|
}
|
|
|
|
protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Size availableSize)
|
|
{
|
|
if (Control.Parent != null)
|
|
return base.MeasureOverride(availableSize);
|
|
else
|
|
{
|
|
if (Element == null || availableSize.Width * availableSize.Height == 0)
|
|
return new Windows.Foundation.Size(0, 0);
|
|
|
|
Element.IsInNativeLayout = true;
|
|
|
|
double width = Math.Max(0, Element.Width);
|
|
double height = Math.Max(0, Element.Height);
|
|
var result = new Windows.Foundation.Size(width, height);
|
|
|
|
if (Control != null)
|
|
{
|
|
double w = Element.Width;
|
|
double h = Element.Height;
|
|
|
|
if (w == -1)
|
|
w = availableSize.Width;
|
|
|
|
if (h == -1)
|
|
h = availableSize.Height;
|
|
|
|
w = Math.Max(0, w);
|
|
h = Math.Max(0, h);
|
|
|
|
// SwipeLayout sometimes crashes when Measure if not previously fully loaded into the VisualTree.
|
|
Control.Loaded += (sender, args) => { Control.Measure(new Windows.Foundation.Size(w, h)); };
|
|
}
|
|
|
|
Element.IsInNativeLayout = false;
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
void OnSwipeItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
{
|
|
UpdateSwipeItems();
|
|
}
|
|
|
|
void OnSwipeItemsPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
var formsSwipeItems = sender as SwipeItems;
|
|
|
|
if (e.PropertyName == SwipeItems.ModeProperty.PropertyName)
|
|
UpdateSwipeMode(formsSwipeItems);
|
|
else if (e.PropertyName == SwipeItems.SwipeBehaviorOnInvokedProperty.PropertyName)
|
|
UpdateSwipeBehaviorOnInvoked(formsSwipeItems);
|
|
}
|
|
|
|
void OnSwipeItemPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
var formsSwipeItem = sender as SwipeItem;
|
|
|
|
if (e.IsOneOf(
|
|
MenuItem.TextProperty,
|
|
MenuItem.IconImageSourceProperty,
|
|
MenuItem.CommandProperty,
|
|
MenuItem.CommandParameterProperty,
|
|
VisualElement.BackgroundColorProperty))
|
|
UpdateSwipeItem(formsSwipeItem);
|
|
}
|
|
|
|
void UpdateContent()
|
|
{
|
|
if (Element.Content == null)
|
|
return;
|
|
|
|
var renderer = Element.Content.GetOrCreateRenderer();
|
|
Control.Content = renderer?.ContainerElement;
|
|
}
|
|
|
|
void UpdateSwipeItems()
|
|
{
|
|
if (IsValidSwipeItems(Element.LeftItems))
|
|
Control.LeftItems = CreateSwipeItems(SwipeDirection.Left);
|
|
|
|
if (IsValidSwipeItems(Element.RightItems))
|
|
Control.RightItems = CreateSwipeItems(SwipeDirection.Right);
|
|
|
|
if (IsValidSwipeItems(Element.TopItems))
|
|
Control.TopItems = CreateSwipeItems(SwipeDirection.Up);
|
|
|
|
if (IsValidSwipeItems(Element.BottomItems))
|
|
Control.BottomItems = CreateSwipeItems(SwipeDirection.Down);
|
|
}
|
|
|
|
void UpdateSwipeMode(SwipeItems swipeItems)
|
|
{
|
|
var windowsSwipeItems = GetWindowsSwipeItems(swipeItems);
|
|
|
|
if (windowsSwipeItems != null)
|
|
windowsSwipeItems.Mode = GetSwipeMode(swipeItems.Mode);
|
|
}
|
|
|
|
void UpdateSwipeBehaviorOnInvoked(SwipeItems swipeItems)
|
|
{
|
|
var windowsSwipeItems = GetWindowsSwipeItems(swipeItems);
|
|
|
|
if (windowsSwipeItems != null)
|
|
foreach (var windowSwipeItem in windowsSwipeItems.ToList())
|
|
windowSwipeItem.BehaviorOnInvoked = GetSwipeBehaviorOnInvoked(swipeItems.SwipeBehaviorOnInvoked);
|
|
}
|
|
|
|
void UpdateSwipeItem(SwipeItem formsSwipeItem)
|
|
{
|
|
if (formsSwipeItem == null)
|
|
return;
|
|
|
|
var windowsSwipeItem = GetWindowsSwipeItem(formsSwipeItem);
|
|
|
|
if (windowsSwipeItem != null)
|
|
{
|
|
windowsSwipeItem.Text = formsSwipeItem.Text;
|
|
windowsSwipeItem.IconSource = formsSwipeItem.IconImageSource.ToWindowsIconSource();
|
|
windowsSwipeItem.Background = formsSwipeItem.BackgroundColor.ToBrush();
|
|
|
|
var textColor = GetSwipeItemColor(formsSwipeItem.BackgroundColor);
|
|
windowsSwipeItem.Foreground = textColor.ToBrush();
|
|
}
|
|
}
|
|
|
|
bool IsValidSwipeItems(SwipeItems swipeItems)
|
|
{
|
|
return swipeItems != null && swipeItems.Count > 0;
|
|
}
|
|
|
|
void DisposeSwipeItems(Dictionary<WSwipeItem, SwipeItem> list)
|
|
{
|
|
if (list != null)
|
|
{
|
|
foreach (var item in list)
|
|
{
|
|
if (item.Key != null)
|
|
item.Key.Invoked -= OnSwipeItemInvoked;
|
|
if (item.Value != null)
|
|
item.Value.PropertyChanged -= OnSwipeItemPropertyChanged;
|
|
}
|
|
|
|
list.Clear();
|
|
list = null;
|
|
}
|
|
}
|
|
|
|
WSwipeItems CreateSwipeItems(SwipeDirection swipeDirection)
|
|
{
|
|
var swipeItems = new WSwipeItems();
|
|
|
|
SwipeItems items = null;
|
|
|
|
switch (swipeDirection)
|
|
{
|
|
case SwipeDirection.Left:
|
|
DisposeSwipeItems(_leftItems);
|
|
items = Element.LeftItems;
|
|
_leftItems = new Dictionary<WSwipeItem, SwipeItem>();
|
|
break;
|
|
case SwipeDirection.Right:
|
|
DisposeSwipeItems(_rightItems);
|
|
items = Element.RightItems;
|
|
_rightItems = new Dictionary<WSwipeItem, SwipeItem>();
|
|
break;
|
|
case SwipeDirection.Up:
|
|
DisposeSwipeItems(_topItems);
|
|
items = Element.TopItems;
|
|
_topItems = new Dictionary<WSwipeItem, SwipeItem>();
|
|
break;
|
|
case SwipeDirection.Down:
|
|
DisposeSwipeItems(_bottomItems);
|
|
items = Element.BottomItems;
|
|
_bottomItems = new Dictionary<WSwipeItem, SwipeItem>();
|
|
break;
|
|
}
|
|
|
|
items.PropertyChanged += OnSwipeItemsPropertyChanged;
|
|
swipeItems.Mode = GetSwipeMode(items.Mode);
|
|
|
|
foreach (var item in items)
|
|
{
|
|
if (item is SwipeItem formsSwipeItem)
|
|
{
|
|
var textColor = GetSwipeItemColor(formsSwipeItem.BackgroundColor);
|
|
|
|
var windowsSwipeItem = new WSwipeItem
|
|
{
|
|
Background = formsSwipeItem.BackgroundColor.IsDefault ? null : formsSwipeItem.BackgroundColor.ToBrush(),
|
|
Foreground = textColor.ToBrush(),
|
|
IconSource = formsSwipeItem.IconImageSource.ToWindowsIconSource(),
|
|
Text = !string.IsNullOrEmpty(formsSwipeItem.Text) ? formsSwipeItem.Text : string.Empty,
|
|
BehaviorOnInvoked = GetSwipeBehaviorOnInvoked(items.SwipeBehaviorOnInvoked)
|
|
};
|
|
|
|
formsSwipeItem.PropertyChanged += OnSwipeItemPropertyChanged;
|
|
windowsSwipeItem.Invoked += OnSwipeItemInvoked;
|
|
|
|
swipeItems.Add(windowsSwipeItem);
|
|
|
|
FillSwipeItemsCache(swipeDirection, windowsSwipeItem, formsSwipeItem);
|
|
}
|
|
}
|
|
|
|
return swipeItems;
|
|
}
|
|
|
|
void FillSwipeItemsCache(SwipeDirection swipeDirection, WSwipeItem windowsSwipeItem, SwipeItem formsSwipeItem)
|
|
{
|
|
switch (swipeDirection)
|
|
{
|
|
case SwipeDirection.Left:
|
|
_leftItems.Add(windowsSwipeItem, formsSwipeItem);
|
|
break;
|
|
case SwipeDirection.Right:
|
|
_rightItems.Add(windowsSwipeItem, formsSwipeItem);
|
|
break;
|
|
case SwipeDirection.Up:
|
|
_topItems.Add(windowsSwipeItem, formsSwipeItem);
|
|
break;
|
|
case SwipeDirection.Down:
|
|
_bottomItems.Add(windowsSwipeItem, formsSwipeItem);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OnSwipeItemInvoked(WSwipeItem sender, Microsoft.UI.Xaml.Controls.SwipeItemInvokedEventArgs args)
|
|
{
|
|
var windowsSwipeItem = sender;
|
|
var formsSwipeItem = GetFormsSwipeItem(windowsSwipeItem);
|
|
formsSwipeItem?.OnInvoked();
|
|
}
|
|
|
|
WSwipeItems GetWindowsSwipeItems(SwipeItems swipeItems)
|
|
{
|
|
if (swipeItems == Element.LeftItems)
|
|
return Control.LeftItems;
|
|
|
|
if (swipeItems == Element.RightItems)
|
|
return Control.RightItems;
|
|
|
|
if (swipeItems == Element.TopItems)
|
|
return Control.TopItems;
|
|
|
|
if (swipeItems == Element.BottomItems)
|
|
return Control.BottomItems;
|
|
|
|
return null;
|
|
}
|
|
|
|
WSwipeItem GetWindowsSwipeItem(SwipeItem swipeItem)
|
|
{
|
|
if (_leftItems != null)
|
|
return _leftItems.FirstOrDefault(x => x.Value.Equals(swipeItem)).Key;
|
|
|
|
if (_rightItems != null)
|
|
return _rightItems.FirstOrDefault(x => x.Value.Equals(swipeItem)).Key;
|
|
|
|
if (_topItems != null)
|
|
return _topItems.FirstOrDefault(x => x.Value.Equals(swipeItem)).Key;
|
|
|
|
if (_bottomItems != null)
|
|
return _bottomItems.FirstOrDefault(x => x.Value.Equals(swipeItem)).Key;
|
|
|
|
return null;
|
|
}
|
|
|
|
SwipeItem GetFormsSwipeItem(WSwipeItem swipeItem)
|
|
{
|
|
if (_leftItems != null)
|
|
{
|
|
_leftItems.TryGetValue(swipeItem, out SwipeItem formsSwipeItem);
|
|
|
|
if (formsSwipeItem != null)
|
|
return formsSwipeItem;
|
|
}
|
|
|
|
if (_rightItems != null)
|
|
{
|
|
_rightItems.TryGetValue(swipeItem, out SwipeItem formsSwipeItem);
|
|
|
|
if (formsSwipeItem != null)
|
|
return formsSwipeItem;
|
|
}
|
|
|
|
if (_topItems != null)
|
|
{
|
|
_topItems.TryGetValue(swipeItem, out SwipeItem formsSwipeItem);
|
|
|
|
if (formsSwipeItem != null)
|
|
return formsSwipeItem;
|
|
}
|
|
|
|
if (_bottomItems != null)
|
|
{
|
|
_bottomItems.TryGetValue(swipeItem, out SwipeItem formsSwipeItem);
|
|
|
|
if (formsSwipeItem != null)
|
|
return formsSwipeItem;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
WSwipeMode GetSwipeMode(SwipeMode swipeMode)
|
|
{
|
|
switch (swipeMode)
|
|
{
|
|
case SwipeMode.Execute:
|
|
return WSwipeMode.Execute;
|
|
case SwipeMode.Reveal:
|
|
return WSwipeMode.Reveal;
|
|
}
|
|
|
|
return WSwipeMode.Reveal;
|
|
}
|
|
|
|
WSwipeBehaviorOnInvoked GetSwipeBehaviorOnInvoked(SwipeBehaviorOnInvoked swipeBehaviorOnInvoked)
|
|
{
|
|
switch (swipeBehaviorOnInvoked)
|
|
{
|
|
case SwipeBehaviorOnInvoked.Auto:
|
|
return WSwipeBehaviorOnInvoked.Auto;
|
|
case SwipeBehaviorOnInvoked.Close:
|
|
return WSwipeBehaviorOnInvoked.Close;
|
|
case SwipeBehaviorOnInvoked.RemainOpen:
|
|
return WSwipeBehaviorOnInvoked.RemainOpen;
|
|
}
|
|
|
|
return WSwipeBehaviorOnInvoked.Auto;
|
|
}
|
|
|
|
Color GetSwipeItemColor(Color backgroundColor)
|
|
{
|
|
var luminosity = 0.2126 * backgroundColor.R + 0.7152 * backgroundColor.G + 0.0722 * backgroundColor.B;
|
|
|
|
return luminosity < 0.75 ? Color.White : Color.Black;
|
|
}
|
|
|
|
void OnCloseRequested(object sender, EventArgs e)
|
|
{
|
|
if (Control == null)
|
|
return;
|
|
|
|
Control.Close();
|
|
}
|
|
}
|
|
} |