Author Topic: Context Menu  (Read 1431 times)

0 Members and 1 Guest are viewing this topic.

WILL HATCH

  • Bull Frog
  • Posts: 450
Context Menu
« on: November 21, 2017, 03:22:47 PM »
Hi All,
I've got a requirement to sometimes optionally display a context menu mid command.
I started with code from here: (Thanks Andrey!)
Code - C#: [Select]
  1. using wpf = System.Windows;
  2. using acad = Autodesk.AutoCAD.ApplicationServices.Application;
  3. ...
  4. const Int32 offset_x = 0;
  5. const Int32 offset_y = 40;
  6. static Double _x, _y;
  7. ...
  8. public void Initialize() {
  9.         // Create new WPF window for using its as context menu
  10.         wpf.Window win = new wpf.Window();
  11.         wpf.Controls.StackPanel sp = new wpf.Controls.StackPanel();
  12.  
  13.         wpf.Controls.MenuItem _clear = new wpf.Controls.MenuItem();
  14.         _clear.Header = "Clear result";
  15.         _clear.Click += mi_Click;
  16.         sp.Children.Add(_clear);
  17.  
  18.         wpf.Controls.MenuItem _report = new wpf.Controls.MenuItem();
  19.         _report.Header = "Show Report";
  20.         sp.Children.Add(_report);
  21.  
  22.         win.Content = sp;
  23.         win.SizeToContent = wpf.SizeToContent.WidthAndHeight;
  24.         win.WindowStyle = wpf.WindowStyle.None;
  25.         win.ResizeMode = wpf.ResizeMode.NoResize;
  26.         win.WindowStartupLocation = wpf.WindowStartupLocation.Manual;
  27.                                
  28.         _x = System.Windows.Forms.Cursor.Position.X;
  29.         _y = System.Windows.Forms.Cursor.Position.Y;            
  30.  
  31.         win.Activated += win_Activated;
  32.         win.Deactivated += win_Deactivated;
  33.         acad.ShowModelessWindow(win);
  34. }
  35.  
  36. void win_Activated(object sender, EventArgs e) {
  37.     wpf.Window win = (wpf.Window)sender;
  38.     win.Left = _x - win.ActualWidth - offset_x;
  39.     win.Top = _y - win.ActualHeight - offset_y;
  40. }
  41.  
  42. void win_Deactivated(object sender, EventArgs e) {    
  43.         ((wpf.Window)sender).Close();
  44. }
  45.  
  46. void mi_Click(object sender, wpf.RoutedEventArgs e) {
  47.     history.Reset();
  48.     wpf.Window win = ((wpf.Window)((wpf.Controls.StackPanel)
  49.         ((wpf.Controls.MenuItem)sender).Parent).Parent);
  50.     win.Deactivated -= win_Deactivated;
  51.     win.Close();
  52. }
  53.  
  54. void clear_Click(object sender, EventArgs e) {
  55.     history.Reset();
  56. }
  57.  

I just wanted to kick back the modifications to suit the needs here. The key difference is that I'm passing in a list of objects that hold a bunch of data, I store a reference to each object in the Tag of each MenuItem. The object points to an image file which is then loaded into the tooltip for display and finally the selected item is added to a queue for further processing elsewhere.

Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using windows = System.Windows;
  7. using acad = Autodesk.AutoCAD.ApplicationServices.Application;
  8. using Autodesk.AutoCAD.EditorInput;
  9. using Autodesk.AutoCAD.ApplicationServices;
  10. using Autodesk.AutoCAD.DatabaseServices;
  11.  
  12. namespace .AddinExtension
  13. {
  14.     class DataDisplay
  15.     {
  16.  
  17.         const Int32 offset_x = 0;
  18.         const Int32 offset_y = 40;
  19.         static Double _x, _y;
  20.         windows.Window win;
  21.         public DataDisplay(List<EquipCableSymbolData> displayData)
  22.         {
  23.            
  24.             // Create new WPF window for using its as context menu
  25.            
  26.             win = new windows.Window();
  27.             win.KeyUp += Win_KeyUp;
  28.             windows.Controls.StackPanel sp = new windows.Controls.StackPanel();
  29.             foreach (var item in displayData)
  30.             {
  31.                 windows.Controls.MenuItem menuItem = new windows.Controls.MenuItem();
  32.                 menuItem.Header = GetTag(item);
  33.                 menuItem.Tag = item;
  34.                 menuItem.ToolTip = new windows.Controls.StackPanel();
  35.                 menuItem.ToolTipOpening += MenuItem_ToolTipOpening;
  36.                 menuItem.Click += MenuItem_Click;
  37.                 sp.Children.Add(menuItem);
  38.             }
  39.  
  40.             win.Content = sp;
  41.             win.SizeToContent = windows.SizeToContent.WidthAndHeight;
  42.             win.WindowStyle = windows.WindowStyle.None;
  43.             win.ResizeMode = windows.ResizeMode.NoResize;
  44.             win.WindowStartupLocation = windows.WindowStartupLocation.Manual;
  45.  
  46.             _x = windows.Forms.Cursor.Position.X;
  47.             _y = windows.Forms.Cursor.Position.Y;
  48.  
  49.             win.Activated += win_Activated;
  50.             win.Deactivated += win_Deactivated;
  51.             acad.ShowModelessWindow(win);
  52.         }
  53.  
  54.         private void Win_KeyUp(object sender, windows.Input.KeyEventArgs e)
  55.         {
  56.             if (e.Key == windows.Input.Key.Escape)
  57.             {
  58.                 win.Deactivated -= win_Deactivated;
  59.                 win.Close();
  60.             }
  61.         }
  62.  
  63.         private void MenuItem_ToolTipOpening(object sender, windows.Controls.ToolTipEventArgs e)
  64.         {
  65.             var menuItem = (windows.Controls.MenuItem)sender;
  66.             var sp = (windows.Controls.StackPanel)menuItem.ToolTip;
  67.             if (sp.Children.Count > 0) return;
  68.             var equip = (EquipCableSymbolData)menuItem.Tag;
  69.             windows.Controls.Image image = new windows.Controls.Image();
  70.             windows.Media.Imaging.BitmapImage bitmap = new windows.Media.Imaging.BitmapImage();
  71.             bitmap.BeginInit();
  72.             bitmap.UriSource = new Uri(equip.GetFullDrawingPicName(), UriKind.RelativeOrAbsolute);
  73.             bitmap.EndInit();
  74.             image.Stretch = windows.Media.Stretch.Fill;
  75.             image.Source = bitmap;
  76.             sp.Children.Add(image);
  77.         }
  78.  
  79.         private void MenuItem_Click(object sender, windows.RoutedEventArgs e)
  80.         {
  81.             //queue that up!
  82.             var item = (windows.Controls.MenuItem)sender;
  83.             var equip = (EquipCableSymbolData)item.Tag;
  84.             QueueUp(equip);
  85.             win.Deactivated -= win_Deactivated;
  86.             win.Close();
  87.            
  88.         }
  89.  
  90.         void win_Activated(object sender, EventArgs e)
  91.         {
  92.             windows.Window win = (windows.Window)sender;
  93.             win.Left = _x - win.ActualWidth - offset_x;
  94.             win.Top = _y - win.ActualHeight - offset_y;
  95.         }
  96.  
  97.         void win_Deactivated(object sender, EventArgs e)
  98.         {
  99.             ((windows.Window)sender).Close();
  100.         }
  101.     }
  102. }
  103.