Modifications you asked about

Sep 6, 2010 at 5:10 PM

I just downloaded the new version, and it looks dramatically different.  If you have not already done something similar, I think you should steal my idea of passing in the width and height of the layout as well as tracking the size of the menu to help you place it better on the screen.  Let me know when you have done it and I will download the new version.

Why I changed it - I found the menus were drifting off the screen to the left and bottom, so I decided to make the menu place itself to avoid that.  You will notice the menu now tracks its total height and the widest entry, to allow it to intelligently place itself.  I try to place it as close to the location clicked as possible.

Do you have any recommendations on a grid that works well with RIA?  I think the best I have found so far is infragistics xamgrid, where I have used some extra code they helped me with to change their filters to ria filters.  My goal is to have excellent access to hierarchical data with good filtering, and performance.  I then add functionality with your popup menu on a rightclick.  The datagrid is missing a filter row, and also row details or nesting.

Here is my revised version – let me know what you think of the improvements.  If you decide to use them and want to credit me, feel free to do so.

 Plus I added this function to allow the menus to link to web sites.  I offer this menu option if the right click is over a URL.

public void GoToURL(string link)
        {

            // if they want to execute a URL go here
            try
            {
                HtmlPage.Window.Navigate(new Uri(link), "_blank", "resizable=yes,scrollbars=yes");

            }
            catch (Exception error) { MessageBoxResult result = MessageBox.Show("Website link " + link + " is not valid (" + error + ")"); }


        }

I call the new popupmenu like this
            var menu = new PopupMenu(e.GetPosition(LayoutRoot).X, 
                e.GetPosition(LayoutRoot).Y,
                LayoutRoot.ActualWidth,
                LayoutRoot.ActualHeight );



public partial class PopupMenu : UserControl
 {
  public delegate void MenuSelectDelegate();
     public double Xmax, Ymax, Ytotal;
  public PopupMenu(double x, double y, double xmax, double ymax)
  {
   InitializeComponent();
  
   Popup.HorizontalOffset = x; // keep box from floating off the screen
   Popup.VerticalOffset = y; //adjusted for the heigth of the top margin on the page
   Xmax = xmax; Ymax = ymax; Ytotal = 0;
      
  }
  public void Add(string text, MenuSelectDelegate onSelect)
  {
   var textBlock = new TextBlock();
   textBlock.Text = text;
   textBlock.Margin = new Thickness(2);
   Popup.HorizontalOffset = Math.Min(Popup.HorizontalOffset, Xmax - textBlock.ActualWidth-20); // make sure we don't overshoot the left of the screen based on the actual size of the text
   Ytotal += textBlock.ActualHeight; // make sure we don't fall off the bottom of the screen based on the actual height of the text cumulatively
   Popup.VerticalOffset = Math.Min(Popup.VerticalOffset, Ymax - Ytotal);
   var border = new Border();
   border.Child = textBlock;
   border.Tag = onSelect;
   border.MouseEnter += new MouseEventHandler(Border_MouseEnter);
   border.MouseLeave += new MouseEventHandler(Border_MouseLeave);
   border.MouseLeftButtonUp += new MouseButtonEventHandler(Border_MouseLeftButtonUp);
   MenuItems.Children.Add(border);
  }
  private void Close()
  {
   Popup.IsOpen = false;
   Visibility = System.Windows.Visibility.Collapsed;
  }
  void Border_MouseEnter(object sender, MouseEventArgs e)
  {
   Border border = (Border)sender;
   border.Background = new SolidColorBrush(Color.FromArgb(255, 0, 0, 128));
   TextBlock textBlock = (TextBlock)border.Child;
   textBlock.Foreground = new SolidColorBrush(Colors.White);
  }
  void Border_MouseLeave(object sender, MouseEventArgs e)
  {
   Border border = (Border)sender;
   border.Background = new SolidColorBrush(Colors.White);
   TextBlock textBlock = (TextBlock)border.Child;
   textBlock.Foreground = new SolidColorBrush(Colors.Black);
  }
  void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  {
   Close();
   Border border = (Border)sender;
   MenuSelectDelegate onSelect = (MenuSelectDelegate)border.Tag;
   onSelect();
  }
  private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  {
   Close();
  }
 }
}