| File: IndicatorView\IndicatorStackLayout.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
using System.ComponentModel; using Microsoft.Maui.Controls.Shapes; using Microsoft.Maui.Graphics; namespace Microsoft.Maui.Controls { internal class IndicatorStackLayout : StackLayout { readonly IndicatorView _indicatorView; public IndicatorStackLayout(IndicatorView indicatorView) { _indicatorView = indicatorView; Orientation = StackOrientation.Horizontal; _indicatorView.PropertyChanged += IndicatorViewPropertyChanged; } protected override void OnChildAdded(Element child) { base.OnChildAdded(child); if (child is View view) { var tapGestureRecognizer = new TapGestureRecognizer { Command = new Command(sender => _indicatorView.Position = Children.IndexOf(sender)), CommandParameter = view }; view.GestureRecognizers.Add(tapGestureRecognizer); } } void IndicatorViewPropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == IndicatorView.IndicatorsShapeProperty.PropertyName || e.PropertyName == IndicatorView.IndicatorTemplateProperty.PropertyName) { ResetIndicators(); } if (e.PropertyName == IndicatorView.MaximumVisibleProperty.PropertyName || e.PropertyName == IndicatorView.PositionProperty.PropertyName || e.PropertyName == IndicatorView.HideSingleProperty.PropertyName || e.PropertyName == IndicatorView.IndicatorColorProperty.PropertyName || e.PropertyName == IndicatorView.SelectedIndicatorColorProperty.PropertyName || e.PropertyName == IndicatorView.IndicatorSizeProperty.PropertyName) { ResetIndicatorStyles(); } } void ResetIndicatorStyles() { try { BatchBegin(); ResetIndicatorStylesNonBatch(); } finally { BatchCommit(); } } internal void ResetIndicators() { try { BatchBegin(); BindIndicatorItems(); } finally { ResetIndicatorStylesNonBatch(); BatchCommit(); } } internal void ResetIndicatorCount(int oldCount) { try { BatchBegin(); if (oldCount < 0) { oldCount = 0; } if (oldCount > _indicatorView.Count) { return; } BindIndicatorItems(); } finally { ResetIndicatorStylesNonBatch(); BatchCommit(); } } void ResetIndicatorStylesNonBatch() { var indicatorCount = _indicatorView.Count; var childrenCount = Children.Count; for (int index = 0; index < childrenCount; index++) { var maxVisible = _indicatorView.MaximumVisible; var position = _indicatorView.Position; var selectedIndex = position >= maxVisible ? maxVisible - 1 : position; bool isSelected = index == selectedIndex; var visualElement = Children[index] as VisualElement; if (visualElement is null) { return; } visualElement.BackgroundColor = isSelected ? GetColorOrDefault(_indicatorView.SelectedIndicatorColor, Colors.Gray) : GetColorOrDefault(_indicatorView.IndicatorColor, Colors.Silver); VisualStateManager.GoToState(visualElement, isSelected ? VisualStateManager.CommonStates.Selected : VisualStateManager.CommonStates.Normal); } IsVisible = indicatorCount > 1 || !_indicatorView.HideSingle; } Color GetColorOrDefault(Color? color, Color defaultColor) => color ?? defaultColor; void BindIndicatorItems() { var indicatorSize = _indicatorView.IndicatorSize > 0 ? _indicatorView.IndicatorSize : 10; var indicatorTemplate = _indicatorView.IndicatorTemplate ??= new DataTemplate(() => new Border { Padding = 0, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center, WidthRequest = indicatorSize, HeightRequest = indicatorSize, StrokeShape = new RoundRectangle() { CornerRadius = _indicatorView.IndicatorsShape == IndicatorShape.Circle ? (float)indicatorSize / 2 : 0, Stroke = Colors.Transparent } }); BindableLayout.SetItemsSource(this, _indicatorView.ItemsSource); BindableLayout.SetItemTemplate(this, indicatorTemplate); } public void Remove() { _indicatorView.PropertyChanged -= IndicatorViewPropertyChanged; } } }