fix: context menu did NOT closed after its placement target being recycled (#140)

This commit is contained in:
leo 2024-05-23 21:24:22 +08:00
parent e9208ef112
commit 0dea7ed0e2
11 changed files with 54 additions and 38 deletions

View file

@ -299,7 +299,8 @@ namespace SourceGit.Views
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(copy); menu.Items.Add(copy);
menu.Open(TextArea.TextView);
TextArea.TextView.OpenContextMenu(menu);
e.Handled = true; e.Handled = true;
} }

View file

@ -24,7 +24,7 @@ namespace SourceGit.Views
{ {
var detail = DataContext as ViewModels.CommitDetail; var detail = DataContext as ViewModels.CommitDetail;
var menu = detail.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change); var menu = detail.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change);
menu.Open(datagrid); datagrid.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
@ -39,7 +39,7 @@ namespace SourceGit.Views
if (node != null && !node.IsFolder) if (node != null && !node.IsFolder)
{ {
var menu = detail.CreateChangeContextMenu(node.Backend as Models.Change); var menu = detail.CreateChangeContextMenu(node.Backend as Models.Change);
menu.Open(view); view.OpenContextMenu(menu);
} }
} }

View file

@ -33,7 +33,7 @@ namespace SourceGit.Views
} }
var menu = detail.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change); var menu = detail.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change);
menu.Open(datagrid); datagrid.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
} }

View file

@ -0,0 +1,25 @@
using System;
using System.ComponentModel;
using Avalonia.Controls;
namespace SourceGit.Views
{
public static class ContextMenuExtension
{
public static void OpenContextMenu(this Control control, ContextMenu menu)
{
menu.PlacementTarget = control;
menu.Closing += OnContextMenuClosing; // Clear context menu because it is dynamic.
control.ContextMenu = menu;
control.ContextMenu.Open();
}
private static void OnContextMenuClosing(object sender, CancelEventArgs e)
{
if (sender is ContextMenu menu && menu.PlacementTarget != null)
menu.PlacementTarget.ContextMenu = null;
}
}
}

View file

@ -300,7 +300,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.Histories histories) if (DataContext is ViewModels.Histories histories)
{ {
var menu = histories.MakeContextMenu(); var menu = histories.MakeContextMenu();
menu?.Open(sender as Control); (sender as Control)?.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
} }

View file

@ -66,13 +66,10 @@ namespace SourceGit.Views
if (sender is Button button && DataContext is ViewModels.Repository repo) if (sender is Button button && DataContext is ViewModels.Repository repo)
{ {
var menu = repo.CreateContextMenuForExternalTools(); var menu = repo.CreateContextMenuForExternalTools();
if (menu != null) button.OpenContextMenu(menu);
{
menu.Open(button);
e.Handled = true; e.Handled = true;
} }
} }
}
private void OnLocalBranchTreeLostFocus(object sender, RoutedEventArgs e) private void OnLocalBranchTreeLostFocus(object sender, RoutedEventArgs e)
{ {
@ -201,8 +198,7 @@ namespace SourceGit.Views
if (node.IsBranch && DataContext is ViewModels.Repository repo) if (node.IsBranch && DataContext is ViewModels.Repository repo)
{ {
var menu = repo.CreateContextMenuForLocalBranch(node.Backend as Models.Branch); var menu = repo.CreateContextMenuForLocalBranch(node.Backend as Models.Branch);
if (menu != null) grid.OpenContextMenu(menu);
menu.Open(grid);
} }
} }
@ -218,14 +214,12 @@ namespace SourceGit.Views
if (node.IsRemote) if (node.IsRemote)
{ {
var menu = repo.CreateContextMenuForRemote(node.Backend as Models.Remote); var menu = repo.CreateContextMenuForRemote(node.Backend as Models.Remote);
if (menu != null) grid.OpenContextMenu(menu);
menu.Open(grid);
} }
else if (node.IsBranch) else if (node.IsBranch)
{ {
var menu = repo.CreateContextMenuForRemoteBranch(node.Backend as Models.Branch); var menu = repo.CreateContextMenuForRemoteBranch(node.Backend as Models.Branch);
if (menu != null) grid.OpenContextMenu(menu);
menu.Open(grid);
} }
} }
@ -238,8 +232,7 @@ namespace SourceGit.Views
{ {
var tag = datagrid.SelectedItem as Models.Tag; var tag = datagrid.SelectedItem as Models.Tag;
var menu = repo.CreateContextMenuForTag(tag); var menu = repo.CreateContextMenuForTag(tag);
if (menu != null) datagrid.OpenContextMenu(menu);
menu.Open(datagrid);
} }
e.Handled = true; e.Handled = true;
@ -251,8 +244,7 @@ namespace SourceGit.Views
{ {
var submodule = datagrid.SelectedItem as string; var submodule = datagrid.SelectedItem as string;
var menu = repo.CreateContextMenuForSubmodule(submodule); var menu = repo.CreateContextMenuForSubmodule(submodule);
if (menu != null) datagrid.OpenContextMenu(menu);
menu.Open(datagrid);
} }
e.Handled = true; e.Handled = true;
@ -263,8 +255,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.Repository repo) if (DataContext is ViewModels.Repository repo)
{ {
var menu = repo.CreateContextMenuForGitFlow(); var menu = repo.CreateContextMenuForGitFlow();
if (menu != null) (sender as Control)?.OpenContextMenu(menu);
menu.Open(sender as Button);
} }
e.Handled = true; e.Handled = true;

View file

@ -25,7 +25,7 @@ namespace SourceGit.Views
{ {
var compare = DataContext as ViewModels.RevisionCompare; var compare = DataContext as ViewModels.RevisionCompare;
var menu = compare.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change); var menu = compare.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change);
menu.Open(datagrid); datagrid.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
@ -40,7 +40,7 @@ namespace SourceGit.Views
if (node != null && !node.IsFolder) if (node != null && !node.IsFolder)
{ {
var menu = compare.CreateChangeContextMenu(node.Backend as Models.Change); var menu = compare.CreateChangeContextMenu(node.Backend as Models.Change);
menu.Open(view); view.OpenContextMenu(menu);
} }
} }

View file

@ -198,7 +198,8 @@ namespace SourceGit.Views
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(copy); menu.Items.Add(copy);
menu.Open(TextArea.TextView);
TextArea.TextView.OpenContextMenu(menu);
e.Handled = true; e.Handled = true;
} }
@ -219,7 +220,7 @@ namespace SourceGit.Views
if (!node.IsFolder) if (!node.IsFolder)
{ {
var menu = detail.CreateRevisionFileContextMenu(node.Backend as Models.Object); var menu = detail.CreateRevisionFileContextMenu(node.Backend as Models.Object);
menu.Open(sender as Control); (sender as Control)?.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;

View file

@ -320,7 +320,8 @@ namespace SourceGit.Views
}; };
menu.Items.Add(copy); menu.Items.Add(copy);
menu.Open(TextArea.TextView);
TextArea.TextView.OpenContextMenu(menu);
e.Handled = true; e.Handled = true;
} }
@ -731,7 +732,8 @@ namespace SourceGit.Views
}; };
menu.Items.Add(copy); menu.Items.Add(copy);
menu.Open(TextArea.TextView);
TextArea.TextView.OpenContextMenu(menu);
e.Handled = true; e.Handled = true;
} }

View file

@ -42,7 +42,7 @@ namespace SourceGit.Views
if (sender is Grid grid && DataContext is ViewModels.Welcome vm) if (sender is Grid grid && DataContext is ViewModels.Welcome vm)
{ {
var menu = vm.CreateContextMenu(grid.DataContext as ViewModels.RepositoryNode); var menu = vm.CreateContextMenu(grid.DataContext as ViewModels.RepositoryNode);
menu?.Open(grid); grid.OpenContextMenu(menu);
e.Handled = true; e.Handled = true;
} }
} }

View file

@ -205,8 +205,7 @@ namespace SourceGit.Views
} }
var menu = vm.CreateContextMenuForUnstagedChanges(selected); var menu = vm.CreateContextMenuForUnstagedChanges(selected);
if (menu != null) datagrid.OpenContextMenu(menu);
menu.Open(datagrid);
} }
e.Handled = true; e.Handled = true;
@ -225,8 +224,7 @@ namespace SourceGit.Views
} }
var menu = vm.CreateContextMenuForUnstagedChanges(selected); var menu = vm.CreateContextMenuForUnstagedChanges(selected);
if (menu != null) tree.OpenContextMenu(menu);
menu.Open(tree);
} }
e.Handled = true; e.Handled = true;
@ -245,8 +243,7 @@ namespace SourceGit.Views
} }
var menu = vm.CreateContextMenuForStagedChanges(selected); var menu = vm.CreateContextMenuForStagedChanges(selected);
if (menu != null) datagrid.OpenContextMenu(menu);
menu.Open(datagrid);
} }
e.Handled = true; e.Handled = true;
@ -265,8 +262,7 @@ namespace SourceGit.Views
} }
var menu = vm.CreateContextMenuForStagedChanges(selected); var menu = vm.CreateContextMenuForStagedChanges(selected);
if (menu != null) tree.OpenContextMenu(menu);
menu.Open(tree);
} }
e.Handled = true; e.Handled = true;
@ -331,7 +327,7 @@ namespace SourceGit.Views
{ {
var menu = vm.CreateContextMenuForCommitMessages(); var menu = vm.CreateContextMenuForCommitMessages();
menu.Placement = PlacementMode.TopEdgeAlignedLeft; menu.Placement = PlacementMode.TopEdgeAlignedLeft;
menu.Open(button); button.OpenContextMenu(menu);
e.Handled = true; e.Handled = true;
} }
} }