Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
#nullable enable
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
*REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultForegroundColor -> Microsoft.Maui.Graphics.Color
*REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultTitleColor -> Microsoft.Maui.Graphics.Color
*REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultUnselectedColor -> Microsoft.Maui.Graphics.Color
Expand All @@ -8,9 +9,9 @@
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView<TItemsView, TAdapter, TItemsViewSource>.OnInterceptTouchEvent(Android.Views.MotionEvent e) -> bool
~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView<TItemsView, TAdapter, TItemsViewSource>.OnTouchEvent(Android.Views.MotionEvent e) -> bool
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.OnHiddenChanged(bool hidden) -> void
~override Microsoft.Maui.Controls.Handlers.Items.RecyclerViewScrollListener<TItemsView, TItemsViewSource>.OnScrollStateChanged(AndroidX.RecyclerView.Widget.RecyclerView recyclerView, int newState) -> void
~override Microsoft.Maui.Controls.Handlers.Items.SelectableItemsViewAdapter<TItemsView, TItemsSource>.IsSelectionEnabled(Android.Views.ViewGroup parent, int viewType) -> bool
override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.OnHiddenChanged(bool hidden) -> void
override Microsoft.Maui.Controls.SwipeItemView.IsEnabledCore.get -> bool
~override Microsoft.Maui.Controls.RadioButton.OnPropertyChanged(string propertyName = null) -> void
override Microsoft.Maui.Controls.TitleBar.OnBindingContextChanged() -> void
17 changes: 9 additions & 8 deletions src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#nullable enable
#nullable enable
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.Handlers.Items.MauiCollectionView.AddSubview(UIKit.UIView! view) -> void
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.Dispose(bool disposing) -> void
~override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController.LoadView() -> void
*REMOVED*~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRootRenderer.TraitCollectionDidChange(UIKit.UITraitCollection previousTraitCollection) -> void
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.DisconnectHandler(UIKit.UIView platformView) -> void
~override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.NumberOfSections(UIKit.UICollectionView collectionView) -> nint
override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.UpdateFlowDirection() -> void
~override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellItemRenderer.ViewDidAppear(bool animated) -> void
~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.DidMoveToParentViewController(UIKit.UIViewController parent) -> void
*REMOVED*~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRootRenderer.TraitCollectionDidChange(UIKit.UITraitCollection previousTraitCollection) -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController.LoadView() -> void
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
override Microsoft.Maui.Controls.SwipeItemView.IsEnabledCore.get -> bool
~override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.NumberOfSections(UIKit.UICollectionView collectionView) -> nint
~override Microsoft.Maui.Controls.RadioButton.OnPropertyChanged(string propertyName = null) -> void
override Microsoft.Maui.Controls.TitleBar.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.UpdateFlowDirection() -> void
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#nullable enable
#nullable enable
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.Handlers.Items.MauiCollectionView.AddSubview(UIKit.UIView! view) -> void
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.Dispose(bool disposing) -> void
~override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController.LoadView() -> void
*REMOVED*~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRootRenderer.TraitCollectionDidChange(UIKit.UITraitCollection previousTraitCollection) -> void
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.DisconnectHandler(UIKit.UIView platformView) -> void
~override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.NumberOfSections(UIKit.UICollectionView collectionView) -> nint
override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.UpdateFlowDirection() -> void
~override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellItemRenderer.ViewDidAppear(bool animated) -> void
~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.DidMoveToParentViewController(UIKit.UIViewController parent) -> void
*REMOVED*~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRootRenderer.TraitCollectionDidChange(UIKit.UITraitCollection previousTraitCollection) -> void
override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController.LoadView() -> void
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
override Microsoft.Maui.Controls.SwipeItemView.IsEnabledCore.get -> bool
~override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.NumberOfSections(UIKit.UICollectionView collectionView) -> nint
~override Microsoft.Maui.Controls.RadioButton.OnPropertyChanged(string propertyName = null) -> void
override Microsoft.Maui.Controls.TitleBar.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2<TItemsView>.UpdateFlowDirection() -> void
3 changes: 2 additions & 1 deletion src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable
#nullable enable
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
~override Microsoft.Maui.Controls.RadioButton.OnPropertyChanged(string propertyName = null) -> void
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.SwipeItemView.IsEnabledCore.get -> bool
override Microsoft.Maui.Controls.TitleBar.OnBindingContextChanged() -> void
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable
#nullable enable
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
~override Microsoft.Maui.Controls.RadioButton.OnPropertyChanged(string propertyName = null) -> void
override Microsoft.Maui.Controls.GraphicsView.OnBindingContextChanged() -> void
override Microsoft.Maui.Controls.SwipeItemView.IsEnabledCore.get -> bool
override Microsoft.Maui.Controls.TitleBar.OnBindingContextChanged() -> void
49 changes: 16 additions & 33 deletions src/Controls/src/Core/SwipeView/SwipeItemView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@
using System;
using System.ComponentModel;
using System.Windows.Input;
using Microsoft.Maui.Controls.Internals;

namespace Microsoft.Maui.Controls
{
/// <summary>
/// Represents a swipe item that displays custom content in a <see cref="SwipeView"/>.
/// </summary>
[ContentProperty(nameof(Content))]
public partial class SwipeItemView : ContentView, Controls.ISwipeItem, Maui.ISwipeItemView
public partial class SwipeItemView : ContentView, Controls.ISwipeItem, Maui.ISwipeItemView, ICommandElement
{
/// <summary>Bindable property for <see cref="Command"/>.</summary>
public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(SwipeItemView), null,
propertyChanging: (bo, o, n) => ((SwipeItemView)bo).OnCommandChanging(),
propertyChanged: (bo, o, n) => ((SwipeItemView)bo).OnCommandChanged());
propertyChanging: CommandElement.OnCommandChanging,
propertyChanged: CommandElement.OnCommandChanged);

/// <summary>Bindable property for <see cref="CommandParameter"/>.</summary>
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(nameof(CommandParameter), typeof(object), typeof(SwipeItemView), null,
propertyChanged: (bo, o, n) => ((SwipeItemView)bo).OnCommandParameterChanged());
propertyChanged: CommandElement.OnCommandParameterChanged);

static SwipeItemView()
{
CommandProperty.DependsOn(CommandParameterProperty);
}

/// <summary>
/// Gets or sets the command invoked when this swipe item is activated. This is a bindable property.
Expand Down Expand Up @@ -52,35 +58,12 @@ public void OnInvoked()
Invoked?.Invoke(this, EventArgs.Empty);
}

void OnCommandChanged()
{
IsEnabled = Command?.CanExecute(CommandParameter) ?? true;

if (Command == null)
return;

Command.CanExecuteChanged += OnCommandCanExecuteChanged;
}

void OnCommandChanging()
{
if (Command == null)
return;

Command.CanExecuteChanged -= OnCommandCanExecuteChanged;
}

void OnCommandParameterChanged()
{
if (Command == null)
return;
protected override bool IsEnabledCore =>
base.IsEnabledCore && CommandElement.GetCanExecute(this, CommandProperty);

IsEnabled = Command.CanExecute(CommandParameter);
}
void ICommandElement.CanExecuteChanged(object sender, EventArgs e) =>
RefreshIsEnabledProperty();

void OnCommandCanExecuteChanged(object sender, EventArgs eventArgs)
{
IsEnabled = Command.CanExecute(CommandParameter);
}
WeakCommandSubscription ICommandElement.CleanupTracker { get; set; }
}
}
}
5 changes: 5 additions & 0 deletions src/Controls/tests/Core.UnitTests/CommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ public void ExecuteDoesNotRunIfValueTypeAndSetToNull()
[InlineData(typeof(SearchBar), false)]
[InlineData(typeof(SearchHandler), true)]
[InlineData(typeof(SearchHandler), false)]
[InlineData(typeof(SwipeItemView), true)]
[InlineData(typeof(SwipeItemView), false)]
public async Task CommandsSubscribedToCanExecuteCollect(Type controlType, bool useWeakEventHandler)
{
// Create a view model with a Command
Expand Down Expand Up @@ -310,6 +312,9 @@ public async Task CommandsSubscribedToCanExecuteCollect(Type controlType, bool u
sh.Command = command;
sh.ClearPlaceholderCommand = command;
break;
case SwipeItemView siv:
siv.Command = command;
break;
}

// Create a weak reference to the button
Expand Down
35 changes: 35 additions & 0 deletions src/Controls/tests/Core.UnitTests/SwipeViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,41 @@ public void TestSwipeItemView()
Assert.NotEmpty(swipeView.LeftItems);
}

[Fact]
public void SwipeItemViewCommandCanExecuteUpdatesIsEnabled()
{
var expectedParameter = new object();
var canExecute = false;
var command = new Command(
_ => { },
parameter => canExecute && ReferenceEquals(parameter, expectedParameter));
var swipeItemView = new SwipeItemView
{
CommandParameter = expectedParameter,
Command = command
};

Assert.False(swipeItemView.IsEnabled);

canExecute = true;
command.ChangeCanExecute();

Assert.True(swipeItemView.IsEnabled);

swipeItemView.CommandParameter = new object();

Assert.False(swipeItemView.IsEnabled);

swipeItemView.CommandParameter = expectedParameter;

Assert.True(swipeItemView.IsEnabled);

swipeItemView.IsEnabled = false;
command.ChangeCanExecute();

Assert.False(swipeItemView.IsEnabled);
}

[Fact]
public void SwipeItemsRemainInLogicalTreeWhenContentIsSet()
{
Expand Down
Loading