First pass at tab view
This commit is contained in:
parent
7560e122f8
commit
945b7e8e11
@ -1,4 +1,4 @@
|
|||||||
using CarouselView.FormsPlugin.Abstractions;
|
// using CarouselView.FormsPlugin.Abstractions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -10,7 +10,7 @@ using Aurora.Design.Converters;
|
|||||||
namespace Aurora.Design.Components.TabView
|
namespace Aurora.Design.Components.TabView
|
||||||
{
|
{
|
||||||
public delegate void PositionChangingEventHandler(object sender, PositionChangingEventArgs e);
|
public delegate void PositionChangingEventHandler(object sender, PositionChangingEventArgs e);
|
||||||
public delegate void PositionChangedEventHandler(object sender, PositionChangedEventArgs e);
|
public delegate void PositionChangedEventHandler(object sender, TabChangedEventArgs e);
|
||||||
|
|
||||||
public class PositionChangingEventArgs : EventArgs
|
public class PositionChangingEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
@ -19,7 +19,7 @@ namespace Aurora.Design.Components.TabView
|
|||||||
public int OldPosition { get; set; }
|
public int OldPosition { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PositionChangedEventArgs : EventArgs
|
public class TabChangedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public int NewPosition { get; set; }
|
public int NewPosition { get; set; }
|
||||||
public int OldPosition { get; set; }
|
public int OldPosition { get; set; }
|
||||||
@ -36,19 +36,21 @@ namespace Aurora.Design.Components.TabView
|
|||||||
{
|
{
|
||||||
private StackLayout _mainContainerSL;
|
private StackLayout _mainContainerSL;
|
||||||
private Grid _headerContainerGrid;
|
private Grid _headerContainerGrid;
|
||||||
private CarouselViewControl _carouselView;
|
// private CarouselViewControl _carouselView;
|
||||||
private ScrollView _tabHeadersContainerSv;
|
private ScrollView _tabHeadersContainerSv;
|
||||||
|
|
||||||
|
private ContentPresenter _tabPresenter;
|
||||||
|
|
||||||
public event PositionChangingEventHandler PositionChanging;
|
public event PositionChangingEventHandler PositionChanging;
|
||||||
public event PositionChangedEventHandler PositionChanged;
|
public event PositionChangedEventHandler PositionChanged;
|
||||||
|
|
||||||
protected virtual void OnPositionChanging(ref PositionChangingEventArgs e)
|
protected virtual void OnTabChanging(ref PositionChangingEventArgs e)
|
||||||
{
|
{
|
||||||
PositionChangingEventHandler handler = PositionChanging;
|
PositionChangingEventHandler handler = PositionChanging;
|
||||||
handler?.Invoke(this, e);
|
handler?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnPositionChanged(PositionChangedEventArgs e)
|
protected virtual void OnTabChanged(TabChangedEventArgs e)
|
||||||
{
|
{
|
||||||
PositionChangedEventHandler handler = PositionChanged;
|
PositionChangedEventHandler handler = PositionChanged;
|
||||||
handler?.Invoke(this, e);
|
handler?.Invoke(this, e);
|
||||||
@ -108,33 +110,39 @@ namespace Aurora.Design.Components.TabView
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool _supressCarouselViewPositionChangedEvent;
|
private bool _supressCarouselViewPositionChangedEvent;
|
||||||
private void _carouselView_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.PropertyName == nameof(_carouselView.Position) && !_supressCarouselViewPositionChangedEvent)
|
|
||||||
{
|
|
||||||
var positionChangingArgs = new PositionChangingEventArgs()
|
|
||||||
{
|
|
||||||
Canceled = false,
|
|
||||||
NewPosition = _carouselView.Position,
|
|
||||||
OldPosition = SelectedTabIndex
|
|
||||||
};
|
|
||||||
|
|
||||||
OnPositionChanging(ref positionChangingArgs);
|
/// <summary>
|
||||||
|
/// Allows for intercepting carousel property changing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
// private void _carouselView_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
// {
|
||||||
|
// if (e.PropertyName == nameof(_carouselView.Position) && !_supressCarouselViewPositionChangedEvent)
|
||||||
|
// {
|
||||||
|
// var positionChangingArgs = new PositionChangingEventArgs()
|
||||||
|
// {
|
||||||
|
// Canceled = false,
|
||||||
|
// NewPosition = _carouselView.Position,
|
||||||
|
// OldPosition = SelectedTabIndex
|
||||||
|
// };
|
||||||
|
|
||||||
if (positionChangingArgs != null && positionChangingArgs.Canceled)
|
// OnPositionChanging(ref positionChangingArgs);
|
||||||
{
|
|
||||||
_supressCarouselViewPositionChangedEvent = true;
|
|
||||||
_carouselView.PositionSelected -= _carouselView_PositionSelected;
|
|
||||||
_carouselView.PropertyChanged -= _carouselView_PropertyChanged;
|
|
||||||
_carouselView.Position = SelectedTabIndex;
|
|
||||||
_carouselView.PositionSelected += _carouselView_PositionSelected;
|
|
||||||
_carouselView.PropertyChanged += _carouselView_PropertyChanged;
|
|
||||||
_supressCarouselViewPositionChangedEvent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetPosition(positionChangingArgs.NewPosition);
|
// if (positionChangingArgs != null && positionChangingArgs.Canceled)
|
||||||
}
|
// {
|
||||||
}
|
// _supressCarouselViewPositionChangedEvent = true;
|
||||||
|
// _carouselView.PositionSelected -= _carouselView_PositionSelected;
|
||||||
|
// _carouselView.PropertyChanged -= _carouselView_PropertyChanged;
|
||||||
|
// _carouselView.Position = SelectedTabIndex;
|
||||||
|
// _carouselView.PositionSelected += _carouselView_PositionSelected;
|
||||||
|
// _carouselView.PropertyChanged += _carouselView_PropertyChanged;
|
||||||
|
// _supressCarouselViewPositionChangedEvent = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SetPosition(positionChangingArgs.NewPosition);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
@ -158,30 +166,32 @@ namespace Aurora.Design.Components.TabView
|
|||||||
HorizontalOptions = LayoutOptions.FillAndExpand
|
HorizontalOptions = LayoutOptions.FillAndExpand
|
||||||
};
|
};
|
||||||
|
|
||||||
_carouselView = new CarouselViewControl
|
_tabPresenter = new ContentPresenter();
|
||||||
{
|
// _carouselView = new CarouselViewControl
|
||||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
// {
|
||||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
// HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||||
HeightRequest = ContentHeight,
|
// VerticalOptions = LayoutOptions.FillAndExpand,
|
||||||
ShowArrows = false,
|
// HeightRequest = ContentHeight,
|
||||||
ShowIndicators = false,
|
// ShowArrows = false,
|
||||||
BindingContext = this
|
// ShowIndicators = false,
|
||||||
};
|
// BindingContext = this
|
||||||
|
// };
|
||||||
|
|
||||||
_carouselView.PropertyChanged += _carouselView_PropertyChanged;
|
// _carouselView.PropertyChanged += _carouselView_PropertyChanged;
|
||||||
_carouselView.PositionSelected += _carouselView_PositionSelected;
|
// _carouselView.PositionSelected += _carouselView_PositionSelected;
|
||||||
|
|
||||||
_mainContainerSL = new StackLayout
|
_mainContainerSL = new StackLayout
|
||||||
{
|
{
|
||||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||||
Children = { _tabHeadersContainerSv, _carouselView },
|
Children = { _tabHeadersContainerSv, _tabPresenter },
|
||||||
|
// Children = { _tabHeadersContainerSv, _carouselView }, //Need to set new child in place of carousel
|
||||||
Spacing = 0
|
Spacing = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
Content = _mainContainerSL;
|
Content = _mainContainerSL;
|
||||||
ItemSource.CollectionChanged += ItemSource_CollectionChanged;
|
ItemSource.CollectionChanged += ItemSource_CollectionChanged;
|
||||||
SetPosition(SelectedTabIndex, true);
|
SetCurrentTab(SelectedTabIndex, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnBindingContextChanged()
|
protected override void OnBindingContextChanged()
|
||||||
@ -199,13 +209,13 @@ namespace Aurora.Design.Components.TabView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _carouselView_PositionSelected(object sender, PositionSelectedEventArgs e)
|
// private void _carouselView_PositionSelected(object sender, PositionSelectedEventArgs e)
|
||||||
{
|
// {
|
||||||
if (_carouselView.Position != e.NewValue || SelectedTabIndex != e.NewValue)
|
// if (_carouselView.Position != e.NewValue || SelectedTabIndex != e.NewValue)
|
||||||
{
|
// {
|
||||||
SetPosition(e.NewValue);
|
// SetPosition(e.NewValue);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void AddTabToView(TabItem tab)
|
private void AddTabToView(TabItem tab)
|
||||||
{
|
{
|
||||||
@ -266,7 +276,7 @@ namespace Aurora.Design.Components.TabView
|
|||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(TabItem.IsCurrent))
|
if (e.PropertyName == nameof(TabItem.IsCurrent))
|
||||||
{
|
{
|
||||||
SetPosition(ItemSource.IndexOf((TabItem)((BoxView)sender).BindingContext));
|
SetCurrentTab(ItemSource.IndexOf((TabItem)((BoxView)sender).BindingContext));
|
||||||
}
|
}
|
||||||
if (e.PropertyName == nameof(WidthRequest))
|
if (e.PropertyName == nameof(WidthRequest))
|
||||||
{
|
{
|
||||||
@ -282,33 +292,21 @@ namespace Aurora.Design.Components.TabView
|
|||||||
Spacing = 0
|
Spacing = 0
|
||||||
};
|
};
|
||||||
var tapRecognizer = new TapGestureRecognizer();
|
var tapRecognizer = new TapGestureRecognizer();
|
||||||
|
|
||||||
|
//Appears to set the current view
|
||||||
tapRecognizer.Tapped += (object s, EventArgs e) =>
|
tapRecognizer.Tapped += (object s, EventArgs e) =>
|
||||||
{
|
{
|
||||||
_supressCarouselViewPositionChangedEvent = true;
|
// _supressCarouselViewPositionChangedEvent = true;
|
||||||
var capturedIndex = _headerContainerGrid.Children.IndexOf((View)s);
|
var capturedIndex = _headerContainerGrid.Children.IndexOf((View)s);
|
||||||
SetPosition(capturedIndex);
|
SetCurrentTab(capturedIndex);
|
||||||
_supressCarouselViewPositionChangedEvent = false;
|
// _supressCarouselViewPositionChangedEvent = false;
|
||||||
};
|
};
|
||||||
headerItemSL.GestureRecognizers.Add(tapRecognizer);
|
headerItemSL.GestureRecognizers.Add(tapRecognizer);
|
||||||
_headerContainerGrid.Children.Add(headerItemSL, _headerContainerGrid.ColumnDefinitions.Count - 1, 0);
|
_headerContainerGrid.Children.Add(headerItemSL, _headerContainerGrid.ColumnDefinitions.Count - 1, 0);
|
||||||
_carouselView.ItemsSource = ItemSource.Select(t => t.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IsSwipingEnabled
|
//Sets caourselview itemssource to current tab
|
||||||
public bool IsSwipingEnabled
|
// _carouselView.ItemsSource = ItemSource.Select(t => t.Content);
|
||||||
{
|
|
||||||
get { return (bool)GetValue(IsSwipingEnabledProperty); }
|
|
||||||
set { SetValue(IsSwipingEnabledProperty, value); }
|
|
||||||
}
|
}
|
||||||
private static void IsSwipingEnabledChanged(BindableObject bindable, object oldValue, object newValue)
|
|
||||||
{
|
|
||||||
if (bindable is TabViewControl tabViewControl)
|
|
||||||
{
|
|
||||||
tabViewControl._carouselView.IsSwipeEnabled = (bool)newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static readonly BindableProperty IsSwipingEnabledProperty = BindableProperty.Create(nameof(IsSwipingEnabled), typeof(bool), typeof(TabViewControl), true, BindingMode.Default, null, IsSwipingEnabledChanged);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region HeaderBackgroundColor
|
#region HeaderBackgroundColor
|
||||||
public Color HeaderBackgroundColor
|
public Color HeaderBackgroundColor
|
||||||
@ -354,10 +352,11 @@ namespace Aurora.Design.Components.TabView
|
|||||||
}
|
}
|
||||||
private static void ContentHeightChanged(BindableObject bindable, object oldValue, object newValue)
|
private static void ContentHeightChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
{
|
{
|
||||||
if (bindable is TabViewControl tabViewControl && tabViewControl._carouselView != null)
|
throw new NotImplementedException();
|
||||||
{
|
// if (bindable is TabViewControl tabViewControl && tabViewControl._carouselView != null)
|
||||||
tabViewControl._carouselView.HeightRequest = (double)newValue;
|
// {
|
||||||
}
|
// tabViewControl._carouselView.HeightRequest = (double)newValue;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
public static readonly BindableProperty ContentHeightProperty = BindableProperty.Create(nameof(ContentHeight), typeof(double), typeof(TabViewControl), (double)200, BindingMode.Default, null, ContentHeightChanged);
|
public static readonly BindableProperty ContentHeightProperty = BindableProperty.Create(nameof(ContentHeight), typeof(double), typeof(TabViewControl), (double)200, BindingMode.Default, null, ContentHeightChanged);
|
||||||
#endregion
|
#endregion
|
||||||
@ -510,10 +509,9 @@ namespace Aurora.Design.Components.TabView
|
|||||||
public static readonly BindableProperty SelectedTabIndexProperty = BindableProperty.Create(nameof(SelectedTabIndex), typeof(int), typeof(TabViewControl), 0, propertyChanged: OnSelectedTabIndexChanged);
|
public static readonly BindableProperty SelectedTabIndexProperty = BindableProperty.Create(nameof(SelectedTabIndex), typeof(int), typeof(TabViewControl), 0, propertyChanged: OnSelectedTabIndexChanged);
|
||||||
private static void OnSelectedTabIndexChanged(BindableObject bindable, object oldValue, object newValue)
|
private static void OnSelectedTabIndexChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
{
|
{
|
||||||
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null &&
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
tabViewControl._carouselView.Position != (int)newValue)
|
|
||||||
{
|
{
|
||||||
tabViewControl.SetPosition((int)newValue);
|
tabViewControl.SetCurrentTab((int)newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int SelectedTabIndex
|
public int SelectedTabIndex
|
||||||
@ -523,7 +521,7 @@ namespace Aurora.Design.Components.TabView
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void SetPosition(int position, bool initialRun = false)
|
public void SetCurrentTab(int position, bool initialRun = false)
|
||||||
{
|
{
|
||||||
if (SelectedTabIndex == position && !initialRun)
|
if (SelectedTabIndex == position && !initialRun)
|
||||||
{
|
{
|
||||||
@ -537,60 +535,76 @@ namespace Aurora.Design.Components.TabView
|
|||||||
NewPosition = position,
|
NewPosition = position,
|
||||||
OldPosition = oldPosition
|
OldPosition = oldPosition
|
||||||
};
|
};
|
||||||
OnPositionChanging(ref positionChangingArgs);
|
OnTabChanging(ref positionChangingArgs);
|
||||||
|
|
||||||
if (positionChangingArgs != null && positionChangingArgs.Canceled)
|
if (positionChangingArgs != null && positionChangingArgs.Canceled)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((position >= 0 && position < ItemSource.Count) || initialRun)
|
if (((position >= 0 && position < ItemSource.Count) || initialRun) &&
|
||||||
|
oldPosition != position)
|
||||||
{
|
{
|
||||||
if (_carouselView.Position != position || initialRun)
|
if (oldPosition < ItemSource.Count)
|
||||||
{
|
{
|
||||||
_carouselView.PositionSelected -= _carouselView_PositionSelected;
|
ItemSource[oldPosition].IsCurrent = false;
|
||||||
_carouselView.Position = position;
|
|
||||||
_carouselView.PositionSelected += _carouselView_PositionSelected;
|
|
||||||
}
|
}
|
||||||
if (oldPosition != position)
|
_tabPresenter.Content = ItemSource[position].Content;
|
||||||
{
|
ItemSource[position].IsCurrent = true;
|
||||||
if (oldPosition < ItemSource.Count)
|
SelectedTabIndex = position;
|
||||||
{
|
Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
|
||||||
ItemSource[oldPosition].IsCurrent = false;
|
|
||||||
}
|
|
||||||
ItemSource[position].IsCurrent = true;
|
|
||||||
SelectedTabIndex = position;
|
|
||||||
|
|
||||||
Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var positionChangedArgs = new PositionChangedEventArgs()
|
//Need to change to not use carouselView
|
||||||
|
// if ((position >= 0 && position < ItemSource.Count) || initialRun)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// if (_carouselView.Position != position || initialRun)
|
||||||
|
// {
|
||||||
|
// _carouselView.PositionSelected -= _carouselView_PositionSelected;
|
||||||
|
// _carouselView.Position = position;
|
||||||
|
// _carouselView.PositionSelected += _carouselView_PositionSelected;
|
||||||
|
// }
|
||||||
|
// if (oldPosition != position)
|
||||||
|
// {
|
||||||
|
// if (oldPosition < ItemSource.Count)
|
||||||
|
// {
|
||||||
|
// ItemSource[oldPosition].IsCurrent = false;
|
||||||
|
// }
|
||||||
|
// ItemSource[position].IsCurrent = true;
|
||||||
|
// SelectedTabIndex = position;
|
||||||
|
|
||||||
|
// Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
var tabChangedArgs = new TabChangedEventArgs()
|
||||||
{
|
{
|
||||||
NewPosition = SelectedTabIndex,
|
NewPosition = SelectedTabIndex,
|
||||||
OldPosition = oldPosition
|
OldPosition = oldPosition
|
||||||
};
|
};
|
||||||
OnPositionChanged(positionChangedArgs);
|
OnTabChanged(tabChangedArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectNext()
|
public void SelectNext()
|
||||||
{
|
{
|
||||||
SetPosition(SelectedTabIndex + 1);
|
SetCurrentTab(SelectedTabIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectPrevious()
|
public void SelectPrevious()
|
||||||
{
|
{
|
||||||
SetPosition(SelectedTabIndex - 1);
|
SetCurrentTab(SelectedTabIndex - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectFirst()
|
public void SelectFirst()
|
||||||
{
|
{
|
||||||
SetPosition(0);
|
SetCurrentTab(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectLast()
|
public void SelectLast()
|
||||||
{
|
{
|
||||||
SetPosition(ItemSource.Count - 1);
|
SetCurrentTab(ItemSource.Count - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTab(TabItem tab, int position = -1, bool selectNewPosition = false)
|
public void AddTab(TabItem tab, int position = -1, bool selectNewPosition = false)
|
||||||
@ -623,7 +637,7 @@ namespace Aurora.Design.Components.TabView
|
|||||||
_headerContainerGrid.Children.RemoveAt(_headerContainerGrid.Children.Count - 1);
|
_headerContainerGrid.Children.RemoveAt(_headerContainerGrid.Children.Count - 1);
|
||||||
_headerContainerGrid.ColumnDefinitions.Remove(_headerContainerGrid.ColumnDefinitions.Last());
|
_headerContainerGrid.ColumnDefinitions.Remove(_headerContainerGrid.ColumnDefinitions.Last());
|
||||||
}
|
}
|
||||||
_carouselView.ItemsSource = ItemSource.Select(t => t.Content);
|
// _carouselView.ItemsSource = ItemSource.Select(t => t.Content);
|
||||||
SelectedTabIndex = position >= 0 && position < ItemSource.Count ? position : ItemSource.Count - 1;
|
SelectedTabIndex = position >= 0 && position < ItemSource.Count ? position : ItemSource.Count - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user