Skip to content

Commit 4a1bb1c

Browse files
committed
Add context actions and improve menu item handling
- Introduced `ContextActions` property in `MyCV` for better access to context actions. - Updated `FireClicked` method in `MenuItem` to accept an optional `cell` parameter. - Enhanced debug output in `MainPage` for improved context during debugging. - Added `CommandBag` record in `MyCollectionViewHandler` for better command handling. - Subscribed to `ContainerContentChanging` in `CreatePlatformView` for custom behavior. - Improved `OnContainerContentChanging` to utilize `CommandBag` for command execution. - Commented out previous pointer event handling for a streamlined approach. - Introduced `ReflectionEx` class with `CollectionViewModel` method for improved data access.
1 parent da1c799 commit 4a1bb1c

File tree

3 files changed

+101
-66
lines changed

3 files changed

+101
-66
lines changed

samples/PJ.ContextActions.Sample/AttachedP.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class MyCV : CollectionView
1111
new ObservableCollection<MenuItem>(),
1212
propertyChanged: OnContextActionsChanged);
1313

14-
14+
1515

1616
public ObservableCollection<MenuItem> ContextActions
1717
{
@@ -80,7 +80,7 @@ public ICommand? Command
8080

8181
public event EventHandler? Clicked;
8282

83-
internal void FireClicked() => Clicked?.Invoke(this, EventArgs.Empty);
83+
internal void FireClicked(object cell = null!) => Clicked?.Invoke(cell, EventArgs.Empty);
8484

8585
// Inherit BindingContext from parent (e.g., MyCV)
8686
protected override void OnParentSet()

samples/PJ.ContextActions.Sample/MainPage.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ public MainPage()
3030

3131
void MenuItem_Clicked(object sender, EventArgs e)
3232
{
33-
System.Diagnostics.Debug.WriteLine("Primeiro item clicado");
33+
System.Diagnostics.Debug.WriteLine($"Primeiro item clicado: {sender}");
3434
}
3535
}

samples/PJ.ContextActions.Sample/Platforms/Windows/MyCollectionViewHandler.cs

Lines changed: 98 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
using Microsoft.UI.Xaml.Input;
88
using WMenuFlyout = Microsoft.UI.Xaml.Controls.MenuFlyout;
99
using WMenuFlyoutItem = Microsoft.UI.Xaml.Controls.MenuFlyoutItem;
10+
using static System.Reflection.BindingFlags;
1011

1112

1213
namespace PJ.ContextActions.Sample.Platforms.Windows;
1314

15+
record CommandBag(object cvItem, MenuItem item);
1416
public class MyCVHandler : CollectionViewHandler
1517
{
1618
MenuItem[]? menuItems;
17-
CollectionViewSource collectionviewsource = default!;
18-
19-
object[] itemsSource = [];
19+
Command<CommandBag>? mauiCommand;
2020

2121
protected override ListViewBase CreatePlatformView()
2222
{
@@ -25,11 +25,6 @@ protected override ListViewBase CreatePlatformView()
2525
return listViewBase;
2626
}
2727

28-
protected override CollectionViewSource CreateCollectionViewSource()
29-
{
30-
return collectionviewsource = base.CreateCollectionViewSource();
31-
}
32-
3328
// TODO grab the item inside the ItemsSource in a better way
3429
void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
3530
{
@@ -45,20 +40,36 @@ void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEve
4540
menuItems = [.. myCv.ContextActions];
4641
}
4742

48-
itemsSource = [.. (VirtualView.ItemsSource as IEnumerable)];
49-
50-
5143
// Show your MenuFlyout here, and you have access to dataItem
5244
var menuFlyout = new WMenuFlyout();
53-
var index = args.ItemIndex;
45+
46+
var model = args.Item.CollectionViewModel();
47+
48+
mauiCommand ??= new Command<CommandBag>(static bag =>
49+
{
50+
var command = bag.item.Command;
51+
52+
if (command?.CanExecute(bag.cvItem) is true)
53+
{
54+
command.Execute(bag.cvItem);
55+
}
56+
bag.item.FireClicked(bag.cvItem);
57+
});
58+
5459
foreach (var item in menuItems!)
5560
{
5661
item.BindingContext = VirtualView.BindingContext;
57-
menuFlyout.Items.Add(new WMenuFlyoutItem { Text = item.Text, Command = item.Command, CommandParameter = itemsSource[index] });
62+
63+
menuFlyout.Items.Add(new WMenuFlyoutItem
64+
{
65+
Text = item.Text,
66+
Command = mauiCommand,
67+
CommandParameter = new CommandBag(model, item)
68+
});
5869
}
5970

6071

61-
Debug.WriteLine($"#### Index {index} ######");
72+
Debug.WriteLine($"#### Index {args.ItemIndex} ######");
6273

6374
// Remove previous handler to avoid multiple subscriptions
6475
args.ItemContainer.ContextFlyout = menuFlyout;
@@ -67,62 +78,86 @@ void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEve
6778
}
6879

6980
// TODO grab the item inside the ItemsSource in a better way
70-
void ItemContainer_PointerPressed(object sender, PointerRoutedEventArgs e)
71-
{
72-
if (!e.GetCurrentPoint(null).Properties.IsRightButtonPressed)
73-
{
74-
return;
75-
}
76-
77-
// sender is the ListViewItem or GridViewItem
78-
if (sender is not ListViewItem itemContainer)
79-
{
80-
return;
81-
}
82-
83-
// Get the bound data item
84-
85-
var dataItem = itemContainer.Content;
81+
//public void ItemContainer_PointerPressed(object sender, PointerRoutedEventArgs e)
82+
//{
83+
// if (!e.GetCurrentPoint(null).Properties.IsRightButtonPressed)
84+
// {
85+
// return;
86+
// }
87+
88+
// // sender is the ListViewItem or GridViewItem
89+
// if (sender is not ListViewItem itemContainer)
90+
// {
91+
// return;
92+
// }
93+
94+
// // Get the bound data item
95+
96+
// var dataItem = itemContainer.Content;
97+
98+
// var itemsSource = collectionviewsource.Source as IReadOnlyCollection<object> ?? [];
99+
// var index = -1;
100+
101+
// foreach (var element in itemsSource)
102+
// {
103+
// index++;
104+
// if (element == dataItem)
105+
// {
106+
// break;
107+
// }
108+
// }
109+
110+
111+
// var source = VirtualView.ItemsSource;
112+
// index++;
113+
// object myObj = default!;
114+
// foreach (var obj in source)
115+
// {
116+
// index--;
117+
// if (index is 0)
118+
// {
119+
// myObj = obj;
120+
// break;
121+
// }
122+
// }
123+
124+
125+
126+
// // Show your MenuFlyout here, and you have access to dataItem
127+
// var menuFlyout = new WMenuFlyout();
128+
129+
// foreach (var item in menuItems!)
130+
// {
131+
// item.BindingContext = VirtualView.BindingContext;
132+
// menuFlyout.Items.Add(new WMenuFlyoutItem { Text = item.Text, Command = item.Command, CommandParameter = myObj });
133+
// }
134+
135+
// menuFlyout.ShowAt(itemContainer, e.GetCurrentPoint(itemContainer).Position);
136+
137+
// e.Handled = true;
138+
//}
139+
}
86140

87-
var itemsSource = collectionviewsource.Source as IReadOnlyCollection<object> ?? [];
88-
var index = -1;
89-
90-
foreach (var element in itemsSource)
91-
{
92-
index++;
93-
if (element == dataItem)
94-
{
95-
break;
96-
}
97-
}
98141

142+
static class ReflectionEx
143+
{
144+
// Microsoft.Maui.Controls.Platform.ItemTemplateContext
145+
static Type? itemTemplateContextType;
99146

100-
var source = VirtualView.ItemsSource;
101-
index++;
102-
object myObj = default!;
103-
foreach (var obj in source)
104-
{
105-
index--;
106-
if (index is 0)
107-
{
108-
myObj = obj;
109-
break;
110-
}
111-
}
147+
public static object CollectionViewModel(this object item)
148+
{
149+
itemTemplateContextType ??= item.GetType();
112150

151+
var props = itemTemplateContextType.GetProperties();
113152

153+
var propertyInfo = itemTemplateContextType.GetProperty("Item", Instance | Public);
114154

115-
// Show your MenuFlyout here, and you have access to dataItem
116-
var menuFlyout = new WMenuFlyout();
155+
Debug.Assert(propertyInfo is not null);
117156

118-
foreach (var item in menuItems!)
119-
{
120-
item.BindingContext = VirtualView.BindingContext;
121-
menuFlyout.Items.Add(new WMenuFlyoutItem { Text = item.Text, Command = item.Command, CommandParameter = myObj });
122-
}
157+
var value = propertyInfo.GetValue(item, null);
123158

124-
menuFlyout.ShowAt(itemContainer, e.GetCurrentPoint(itemContainer).Position);
159+
Debug.Assert(value is not null);
125160

126-
e.Handled = true;
161+
return value;
127162
}
128-
}
163+
}

0 commit comments

Comments
 (0)