private void mi_Popup(object sender, EventArgs e) { MenuItem miBase = sender as MenuItem; Debug.Assert(miBase != null); if (miBase.MenuItems.Count > 1) { return; // already popped up, has items. } LocaleMenuItemData lmd = m_itemData[miBase]; LocaleMenuItemData lmdFirst = lmd.m_subitems[0]; foreach (LocaleMenuItemData lmdSub in lmd.m_subitems) { // Skip the first item as it was added earlier. if (lmdSub == lmdFirst) { continue; } MenuItem miSub = new MenuItem(lmdSub.m_displayName, new EventHandler(ItemClickHandler)); miBase.MenuItems.Add(miSub); m_itemData[miSub] = lmdSub; } }
private void ItemClickHandler(Object sender, EventArgs e) { var mi = (ToolStripMenuItem)sender; if (mi.Text == FwCoreDlgControls.kstid_None) { m_selectedLocale = null; Text = FwCoreDlgControls.kstid_None; OnLocaleSelected(new EventArgs()); return; } LocaleMenuItemData lmd = m_itemData[mi]; m_selectedLocale = lmd.m_id; Text = lmd.m_displayName; OnLocaleSelected(new EventArgs()); }
private void ItemClickHandler(Object sender, System.EventArgs e) { MenuItem mi = sender as MenuItem; if (mi.Text == m_res.GetString("kstid_None")) { m_selectedLocale = null; this.Text = m_res.GetString("kstid_None"); OnLocaleSelected(new EventArgs()); return; } LocaleMenuItemData lmd = m_itemData[mi]; m_selectedLocale = lmd.m_id; this.Text = lmd.m_displayName; OnLocaleSelected(new EventArgs()); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Raises the click event. /// </summary> /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param> /// ------------------------------------------------------------------------------------ protected override void OnClick(EventArgs e) { ILgIcuLocaleEnumerator locEnum = LgIcuLocaleEnumeratorClass.Create(); var menu = components.ContextMenuStrip("contextMenu"); // Create the various collections we use in the process of assembling // the menu. m_locales = new Dictionary <string, List <LocaleMenuItemData> >(); m_mainItems = new List <LocaleMenuItemData>(); m_itemData = new Dictionary <ToolStripMenuItem, LocaleMenuItemData>(); int cloc = locEnum.Count; for (int iloc = 0; iloc < cloc; iloc++) { string langid = locEnum.get_Language(iloc); string localeid = locEnum.get_Name(iloc); string displayName = locEnum.get_DisplayName(iloc, m_displayLocaleId); List <LocaleMenuItemData> mainItems; if (!m_locales.TryGetValue(langid, out mainItems)) { mainItems = new List <LocaleMenuItemData>(); m_locales[langid] = mainItems; } // Todo: second arg should be display name. var data = new LocaleMenuItemData(localeid, displayName); mainItems.Add(data); } // Generate the secondary items. For each key in m_locales, // 1. If there is just one item in the List and its id is equal to the key, // then this language has only one locale, // the unmodified one that appears in the main list. // 2. If there is more than one item and one of them has an id equal to the key, // make a single item in main list. It is a copy of the item whose id is // equal to the key, that is, the most basic locale for this language. // It has the arraylist for mainItems. // 3. Otherwise, we have a list of locales for which there is no basic locale // whose id is equal to the language id. In this case, we make an item // for each thing in the List, whether many or just one. foreach (KeyValuePair <string, List <LocaleMenuItemData> > kvp in m_locales) { string langid = kvp.Key; List <LocaleMenuItemData> items = kvp.Value; LocaleMenuItemData lmdRootItem = items.FirstOrDefault(lmd => lmd.m_id == langid); // See if there is an item in the array list that matches the langid if (lmdRootItem == null) { // case 3 foreach (LocaleMenuItemData lmd in items) { m_mainItems.Add(lmd); } } else { if (items.Count == 1) { // case 1 var lmdMenu = new LocaleMenuItemData(lmdRootItem.m_id, lmdRootItem.m_displayName); m_mainItems.Add(lmdMenu); } else { // case 2 var lmdMenu = new LocaleMenuItemData(lmdRootItem.m_id, lmdRootItem.m_displayName) { m_subitems = items }; m_mainItems.Add(lmdMenu); } } } // Sort the items in each menu. m_mainItems.Sort(); var NoneData = new LocaleMenuItemData(FwCoreDlgControls.kstid_None, FwCoreDlgControls.kstid_None); var NoneItem = new ToolStripMenuItem(NoneData.m_displayName, null, ItemClickHandler); menu.Items.Add(NoneItem); // This goes strictly at the beginning, irrespective of sorting foreach (LocaleMenuItemData lmd in m_mainItems) { var mi = new ToolStripMenuItem(lmd.m_displayName, null, ItemClickHandler); menu.Items.Add(mi); m_itemData[mi] = lmd; if (lmd.m_subitems != null) { mi.DropDownOpened += mi_Popup; lmd.m_subitems.Sort(); // To make the system realize this item is a submenu, we have to // add at least one item. To save time and space, we don't add the others // until it pops up. LocaleMenuItemData lmdSub = lmd.m_subitems[0]; var miSub = new ToolStripMenuItem(lmdSub.m_displayName, null, ItemClickHandler); mi.DropDownItems.Add(miSub); m_itemData[miSub] = lmdSub; // Turns out popup events don't happen in a .NET submenu, only for the top-level // menu. DavidO has a workaround that should soon be checked in. In the meantime, // generate the submenu at once. This may actually be fast enough to keep permanently. mi_Popup(mi, new EventArgs()); } } if (MiscUtils.IsUnix) { menu.ShowWithOverflow(this, new Point(0, Height)); } else { menu.Show(this, new Point(0, Height)); } Marshal.ReleaseComObject(locEnum); base.OnClick(e); // Review JohnT: is this useful or harmful or neither? MS recommends it. }