зеркало из https://github.com/DeGsoft/maui-linux.git
213 строки
5.0 KiB
C#
213 строки
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Xamarin.Forms
|
|
{
|
|
public abstract class Cell : Element, ICellController
|
|
{
|
|
public const int DefaultCellHeight = 40;
|
|
public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create("IsEnabled", typeof(bool), typeof(Cell), true, propertyChanged: OnIsEnabledPropertyChanged);
|
|
|
|
ObservableCollection<MenuItem> _contextActions;
|
|
|
|
double _height = -1;
|
|
|
|
bool _nextCallToForceUpdateSizeQueued;
|
|
|
|
public IList<MenuItem> ContextActions
|
|
{
|
|
get
|
|
{
|
|
if (_contextActions == null)
|
|
{
|
|
_contextActions = new ObservableCollection<MenuItem>();
|
|
_contextActions.CollectionChanged += OnContextActionsChanged;
|
|
}
|
|
|
|
return _contextActions;
|
|
}
|
|
}
|
|
|
|
public bool HasContextActions
|
|
{
|
|
get { return _contextActions != null && _contextActions.Count > 0 && IsEnabled; }
|
|
}
|
|
|
|
public double Height
|
|
{
|
|
get { return _height; }
|
|
set
|
|
{
|
|
if (_height == value)
|
|
return;
|
|
|
|
OnPropertyChanging("Height");
|
|
OnPropertyChanging("RenderHeight");
|
|
_height = value;
|
|
OnPropertyChanged("Height");
|
|
OnPropertyChanged("RenderHeight");
|
|
}
|
|
}
|
|
|
|
public bool IsEnabled
|
|
{
|
|
get { return (bool)GetValue(IsEnabledProperty); }
|
|
set { SetValue(IsEnabledProperty, value); }
|
|
}
|
|
|
|
public double RenderHeight
|
|
{
|
|
get
|
|
{
|
|
var table = RealParent as TableView;
|
|
if (table != null)
|
|
return table.HasUnevenRows && Height > 0 ? Height : table.RowHeight;
|
|
|
|
var list = RealParent as ListView;
|
|
if (list != null)
|
|
return list.HasUnevenRows && Height > 0 ? Height : list.RowHeight;
|
|
|
|
return DefaultCellHeight;
|
|
}
|
|
}
|
|
|
|
public event EventHandler Appearing;
|
|
|
|
public event EventHandler Disappearing;
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public event EventHandler ForceUpdateSizeRequested;
|
|
|
|
public void ForceUpdateSize()
|
|
{
|
|
if (_nextCallToForceUpdateSizeQueued)
|
|
return;
|
|
|
|
if ((Parent as ListView)?.HasUnevenRows == true)
|
|
{
|
|
_nextCallToForceUpdateSizeQueued = true;
|
|
OnForceUpdateSizeRequested();
|
|
}
|
|
}
|
|
|
|
public event EventHandler Tapped;
|
|
|
|
protected internal virtual void OnTapped()
|
|
{
|
|
if (Tapped != null)
|
|
Tapped(this, EventArgs.Empty);
|
|
}
|
|
|
|
protected virtual void OnAppearing()
|
|
{
|
|
EventHandler handler = Appearing;
|
|
if (handler != null)
|
|
handler(this, EventArgs.Empty);
|
|
}
|
|
|
|
protected override void OnBindingContextChanged()
|
|
{
|
|
base.OnBindingContextChanged();
|
|
|
|
if (HasContextActions)
|
|
{
|
|
for (var i = 0; i < _contextActions.Count; i++)
|
|
SetInheritedBindingContext(_contextActions[i], BindingContext);
|
|
}
|
|
}
|
|
|
|
protected virtual void OnDisappearing()
|
|
{
|
|
EventHandler handler = Disappearing;
|
|
if (handler != null)
|
|
handler(this, EventArgs.Empty);
|
|
}
|
|
|
|
protected override void OnParentSet()
|
|
{
|
|
if (RealParent != null)
|
|
{
|
|
RealParent.PropertyChanged += OnParentPropertyChanged;
|
|
RealParent.PropertyChanging += OnParentPropertyChanging;
|
|
}
|
|
|
|
base.OnParentSet();
|
|
}
|
|
|
|
protected override void OnPropertyChanging(string propertyName = null)
|
|
{
|
|
if (propertyName == "Parent")
|
|
{
|
|
if (RealParent != null)
|
|
{
|
|
RealParent.PropertyChanged -= OnParentPropertyChanged;
|
|
RealParent.PropertyChanging -= OnParentPropertyChanging;
|
|
}
|
|
}
|
|
|
|
base.OnPropertyChanging(propertyName);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public void SendAppearing()
|
|
{
|
|
OnAppearing();
|
|
|
|
var container = RealParent as ListView;
|
|
if (container != null)
|
|
container.SendCellAppearing(this);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public void SendDisappearing()
|
|
{
|
|
OnDisappearing();
|
|
|
|
var container = RealParent as ListView;
|
|
if (container != null)
|
|
container.SendCellDisappearing(this);
|
|
}
|
|
|
|
void OnContextActionsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
{
|
|
for (var i = 0; i < _contextActions.Count; i++)
|
|
SetInheritedBindingContext(_contextActions[i], BindingContext);
|
|
|
|
OnPropertyChanged("HasContextActions");
|
|
}
|
|
|
|
async void OnForceUpdateSizeRequested()
|
|
{
|
|
// don't run more than once per 16 milliseconds
|
|
await Task.Delay(TimeSpan.FromMilliseconds(16));
|
|
EventHandler handler = ForceUpdateSizeRequested;
|
|
if (handler != null)
|
|
handler(this, null);
|
|
|
|
_nextCallToForceUpdateSizeQueued = false;
|
|
}
|
|
|
|
static void OnIsEnabledPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
|
|
{
|
|
(bindable as Cell).OnPropertyChanged("HasContextActions");
|
|
}
|
|
|
|
void OnParentPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
// Technically we might be raising this even if it didn't change, but I'm taking the bet that
|
|
// its uncommon enough that we don't want to take the penalty of N GetValue calls to verify.
|
|
if (e.PropertyName == "RowHeight")
|
|
OnPropertyChanged("RenderHeight");
|
|
}
|
|
|
|
void OnParentPropertyChanging(object sender, PropertyChangingEventArgs e)
|
|
{
|
|
if (e.PropertyName == "RowHeight")
|
|
OnPropertyChanging("RenderHeight");
|
|
}
|
|
}
|
|
} |