mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-03-29 20:33:22 -04:00
2nd attempt
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Version>13.3.2.1</Version>
|
||||
<Version>13.3.2.2</Version>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -4,11 +4,22 @@ using Avalonia.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibationAvalonia.Controls;
|
||||
|
||||
public class DataGridCellContextMenu<TContext> where TContext : class
|
||||
{
|
||||
private static readonly PropertyInfo? DataGridCellOwningColumnProperty =
|
||||
typeof(DataGridCell).GetProperty("OwningColumn", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
private static DataGridColumn? GetDataGridColumn(DataGridCell cell)
|
||||
{
|
||||
if (cell.Tag is DataGridColumn columnFromTag)
|
||||
return columnFromTag;
|
||||
return DataGridCellOwningColumnProperty?.GetValue(cell) as DataGridColumn;
|
||||
}
|
||||
|
||||
public static DataGridCellContextMenu<TContext>? Create(ContextMenu? contextMenu)
|
||||
{
|
||||
DataGrid? grid = null;
|
||||
@@ -22,7 +33,11 @@ public class DataGridCellContextMenu<TContext> where TContext : class
|
||||
parent = parent.Parent;
|
||||
}
|
||||
|
||||
if (grid is null || cell is null || cell.Tag is not DataGridColumn column || contextMenu!.DataContext is not TContext clickedEntry)
|
||||
if (grid is null || cell is null || contextMenu!.DataContext is not TContext clickedEntry)
|
||||
return null;
|
||||
|
||||
var column = GetDataGridColumn(cell);
|
||||
if (column is null)
|
||||
return null;
|
||||
|
||||
var allSelected = grid.SelectedItems.OfType<TContext>().ToArray();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Input.Platform;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.VisualTree;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Styling;
|
||||
using DataLayer;
|
||||
@@ -105,6 +108,46 @@ public partial class ProductsDisplay : UserControl
|
||||
{
|
||||
column.CustomSortComparer = new RowComparer(column);
|
||||
}
|
||||
|
||||
// macOS: control-click may be delivered as left+control or as a secondary click; the default
|
||||
// ContextMenu route can fail on DataGrid cells. Open explicitly after children handle the event.
|
||||
if (Configuration.IsMacOs)
|
||||
{
|
||||
productsGrid.AddHandler(InputElement.PointerPressedEvent, ProductsGrid_PointerPressedMacContextMenu, RoutingStrategies.Bubble, handledEventsToo: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProductsGrid_PointerPressedMacContextMenu(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (DisableContextMenu)
|
||||
return;
|
||||
|
||||
var point = e.GetCurrentPoint(productsGrid);
|
||||
var props = point.Properties;
|
||||
bool isContextGesture = props.IsRightButtonPressed
|
||||
|| (props.IsLeftButtonPressed && e.KeyModifiers.HasFlag(KeyModifiers.Control));
|
||||
|
||||
if (!isContextGesture)
|
||||
return;
|
||||
|
||||
if (e.Source is not Visual visual)
|
||||
return;
|
||||
|
||||
DataGridCell? cell = null;
|
||||
for (Visual? v = visual; v is not null; v = v.GetVisualParent())
|
||||
{
|
||||
if (v is DataGridCell c)
|
||||
{
|
||||
cell = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell?.ContextMenu is not { } contextMenu)
|
||||
return;
|
||||
|
||||
contextMenu.Open(cell);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(Avalonia.Controls.Primitives.TemplateAppliedEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user