Cascaded ContextMenu in WPF ComboBox - c#

I want to create a ComboBox that lets users select items the way the Windows XP start menu allows to select programs:
Is there a way to insert a cascaded ContextMenu inside a ComboBox?
I tried this but it doesn't work properly:
<ComboBox>
<MenuItem Header="Top Level 1">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
</MenuItem>
<MenuItem Header="Top Level 2">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
</MenuItem>
</ComboBox>

You will want to try somthing like this, The next level must be inside the first level.
<Menu Margin="0,0,0,283">
<MenuItem Header="Top Level 1">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
<MenuItem Header="Top Level 2">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
<MenuItem Header="Top Level 3">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
</MenuItem>
</MenuItem>
</MenuItem>
</Menu>

Do you have to use a ComboBox?
Using the Menu control will make your MenuItems work easily... so I would use that instead: http://wpftutorial.net/Menus.html
You can always alter the look of it as well. There are some examples here: http://www.c-sharpcorner.com/uploadfile/mahesh/menus-in-wpf/
Else, did you try to wrap your menuitems in a simply?

Related

WPF MenuItem multi adding.

Error CS0120 An object reference is required for the non-static field,
method, or property 'MainWindow.System' %Path%\MainWindow.g.cs at line
316
I get the code error i mentioned on title when i try to add Sub MenuItems under a SubMenuItem. Here is my Code:
<Menu x:Name="MainMenu" Height="Auto" Width="Auto" VerticalAlignment="Top">
<MenuItem Header="_Menu" x:Name="Menu" Foreground="Black">
<MenuItem x:Name="RestartComputer" Header="_Restart Computer" Click="restart_Click"/>
<MenuItem x:Name="ShutdownComputer" Header="_Shutdown Computer" Click="shutdown_Click"/>
<MenuItem x:Name="OnTop" Header="_Always On Top" Click="OnTop_Click"/>
<Separator Width="Auto" Height="2"/>
<MenuItem x:Name="Exit" Header="_Exit" Click="MenuItem_Click"/>
</MenuItem>
<MenuItem x:Name="ControlPanel" Header="_Control Panel" Height="Auto" Width="Auto" Foreground="Black">
<MenuItem x:Name="Main" Header="Control Panel Main"/>
<MenuItem x:Name="ProgramsAndFeatures" Header="Programs and Features"/>
<MenuItem x:Name="AdministrativeTools" Header="Administrative Tools"/>
<MenuItem x:Name="DeviceManager" Header="Device Manager"/>
<MenuItem x:Name="NetworkAndSharing" Header="Network and Sharing"/>
<MenuItem x:Name="PowerOptions" Header="Power Options"/>
<Separator Width="Auto" Height="2"/>
<MenuItem x:Name="WindowsFirewall" Header="Windows Firewall"/>
<MenuItem x:Name="Display" Header="Display"/>
<Separator Width="Auto" Height="2"/>
<MenuItem x:Name="System" Header="System"/>
<MenuItem x:Name="DevicesAndPrinters" Header="Devices and Printers"/>
</MenuItem>
</Menu>
If i lessen these MenuItems under ControlPanel menu item to 4 or 5 no problem, but if i make them more than 5 or 6 i get the error what can it be ?
And also at MainWindow.g.cs line 316 is this.
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
Use different x:Name for
<MenuItem x:Name="System" Header="System"/>

Taking from XML whole node with LINQ c#

hi this is my xml i want to get only those menuitems which has type = "0". please help. AS you see there is menuitem in menuitem and in menuitem . i want to check all of them and if type is 0 i want to get that .
i want C# code
<Menu>
<menuitem alias="CB6CF9A26E92FB60487B538C57FDD0E9" slot="0" type="1" name="თანხის შეტანა">
<menuitem alias="5A8B27411D011CBE2EAB916A9E6E7B4C" slot="0" type="1" name="ბარათი">
<menuitem alias="B82505AC178863EFF64260EC52E410BE" slot="0" type="0" name="მარჯანიშვილის ფილიალი|VISA CLASSIC|GE****************0082|GEL" />
<menuitem alias="F0CF0D9A4D732C2026948FC34DFAC29F" slot="1" type="0" name="მარჯანიშვილის ფილიალი|VISA CLASSIC|GE****************0082|USD|კურსი - 2.49" />
<menuitem alias="6F6CA87FBACC28E8E5D09E29577B8E2A" slot="2" type="0" name="ცენტრალური ფილიალი|MC STANDARD|GE****************0006|GEL" />
<menuitem alias="329078EA8197E4F153B1B562EA07CD20" slot="3" type="0" name="ცენტრალური ფილიალი|MC STANDARD|GE****************0006|USD|კურსი - 2.49" />
</menuitem>
<menuitem alias="2BC77B16A194A82BF55AC48966CE6141" slot="1" type="1" name="შემნახველი">
<menuitem alias="7B0B015673196CC9FFB4D685B6448410" slot="0" type="0" name="მარჯანიშვილის ფილიალი|ჩემი სეიფი|GE****************0018|GEL" />
</menuitem>
<menuitem alias="1FC50E2144F4DF526D9ABCB45A078547" slot="2" type="1" name="ჩემი სეიფი - IBS(კოდი 3331)" />
</menuitem>
</Menu>
newDocument.SelectNodes("//Menu//menuitem[#type='0']")
this helped me .

Create Vertical Menu

I am try do a menu like the photo below:
I have this code:
<Menu >
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Item1">
<MenuItem Header="SubItem 1">
<MenuItem Header="SubItem 1.1"></MenuItem>
<MenuItem Header="SubItem 1.2"></MenuItem>
<MenuItem Header="SubItem 1.3"></MenuItem>
<MenuItem Header="SubItem 1.4"></MenuItem>
</MenuItem>
<MenuItem Header="SubItem 2"></MenuItem>
<MenuItem Header="SubItem 3"></MenuItem>
<MenuItem Header="SubItem 4"></MenuItem>
</MenuItem>
<MenuItem Header="Item2">
<MenuItem Header="SubItem 1"></MenuItem>
<MenuItem Header="SubItem 2"></MenuItem>
<MenuItem Header="SubItem 3"></MenuItem>
</MenuItem>
</Menu>
but this code returns a menu like in the pictures below:
First appears this:
and when I put the mouse hover the Item 1 appears like this:
I want to that the second level of the Menu open on the right side of the first, like in the first image.
You have to create a custom template for your Menu to achieve your goal.
Here is the default ControlTemplate for Menu, I think the easiest way is to start from that. You will have to add HorizontalOffset and VerticalOffset for the PopUp in the TopLevelHeader template, so you can align it to your needs (or simply set Placement to Right - which is easier in my opinion).
Also, you should set a Width for your menu (either directly or by placing it inside some container that restricts it's Width), otherwise it will take up all the space and the PopUp might not be visible .
I will not replicate the whole XAML here, but here is the important part:
// ...
<!-- TopLevelHeader -->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}"
TargetType="MenuItem">
<Border Name="Border" >
<Grid>
<ContentPresenter
Margin="6,3,6,3"
ContentSource="Header"
RecognizesAccessKey="True" />
<Popup
Name="Popup"
Placement="Right" <!-- This is modified -->
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
// ... (You need all the XAML from the linked MSDN site in your Resources somewhere)
After that you can use your Menu almost exactly like you did (I only added Width):
<Menu Width="300">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Item1">
<MenuItem Header="SubItem 1">
<MenuItem Header="SubItem 1.1"></MenuItem>
<MenuItem Header="SubItem 1.2"></MenuItem>
<MenuItem Header="SubItem 1.3"></MenuItem>
<MenuItem Header="SubItem 1.4"></MenuItem>
</MenuItem>
<MenuItem Header="SubItem 2"></MenuItem>
<MenuItem Header="SubItem 3"></MenuItem>
<MenuItem Header="SubItem 4"></MenuItem>
</MenuItem>
<MenuItem Header="Item2">
<MenuItem Header="SubItem 1"></MenuItem>
<MenuItem Header="SubItem 2"></MenuItem>
<MenuItem Header="SubItem 3"></MenuItem>
</MenuItem>
</Menu>
You might want to name the template and apply it to this Menu directly, not to mess up other Menus in your app...
The result:
Of course some more styling is needed to get the exact result you want, but I hope you got the idea.

Bind WPF combobox submenu item to combobox selecteditem

Inside this combobox I have a menu that contains multiple menus.
This is how it looks:
This is the XAML:
<ComboBox>
<Menu>
<MenuItem Header="Name">
<MenuItem Header="Last" />
<MenuItem Header="First" />
</MenuItem>
</Menu>
<Menu>
<MenuItem Header="Age">
<MenuItem Header="20" />
<MenuItem Header="24" />
</MenuItem>
</Menu>
</ComboBox>
When the user selects "Last"/"First"/"20"/"24" I want the combobox to set its selected item to one of this 4 items.
Is it possible? If yes, how can I do it?
Yes you can do that. But I am not sure if this is the best way cos I dont know your requirement in full.
XAML:
<ComboBox x:Name="cmb1" IsEditable="True" >
<Menu>
<MenuItem Header="Name" >
<MenuItem Click="MenuItem_Click" CommandParameter ="Last" Header="Last"/>
<MenuItem Click="MenuItem_Click" CommandParameter="First" Header="First" />
</MenuItem>
</Menu>
<Menu>
<MenuItem Header="Age">
<MenuItem Header="20" />
<MenuItem Header="24" />
</MenuItem>
</Menu>
</ComboBox>
vb Code:
Private Sub MenuItem_Click(sender As Object, e As RoutedEventArgs)
Me.cmb1.Text = CType(sender, MenuItem).CommandParameter.ToString()
End Sub
c# code :
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem menuItem = sender as MenuItem;
this.cmb1.Text = menuItem.CommandParameter.ToString();
}

WPF find a nested menuitem in code

I have an image that has a nested context menu defined in the XAML (shown below).
I am trying to use a for loop to find a menu and uncheck it using IsChecked=false.
my code is as follows:
for (int i = 1; i <= 16; i++)
{
MenuItem theMenu = (MenuItem)this.FindName("beat" + i.ToString());
theMenu.IsChecked = false;
}
the above does not work and returns a null.
what am I doing wrong!
excerpt from the XAML
<Image x:Name="Options" Height="35" Source="Images/pad-options-button.png" Stretch="Fill" Width="47" Canvas.Left="740" Canvas.Top="293"
MouseUp="Options_MouseUp">
<Image.ContextMenu>
<ContextMenu>
<MenuItem Header="Beats">
<MenuItem Name="beat1" Header="1" Click="MenuBeats_Click"/>
<MenuItem Name="beat2" Header="2" Click="MenuBeats_Click"/>
<MenuItem Name="beat3" Header="3" Click="MenuBeats_Click"/>
<MenuItem Name="beat4" Header="4" Click="MenuBeats_Click"/>
<MenuItem Name="beat5" Header="5" Click="MenuBeats_Click"/>
<MenuItem Name="beat6" Header="6" Click="MenuBeats_Click"/>
<MenuItem Name="beat7" Header="7" Click="MenuBeats_Click"/>
<MenuItem Name="beat8" Header="8" Click="MenuBeats_Click"/>/>
<MenuItem Name="beat9" Header="9" Click="MenuBeats_Click"/>
<MenuItem Name="beat10" Header="10" Click="MenuBeats_Click"/>
<MenuItem Name="beat11" Header="11" Click="MenuBeats_Click"/>
<MenuItem Name="beat12" Header="12" Click="MenuBeats_Click"/>
<MenuItem Name="beat13" Header="13" Click="MenuBeats_Click"/>
<MenuItem Name="beat14" Header="14" Click="MenuBeats_Click"/>
<MenuItem Name="beat15" Header="15" Click="MenuBeats_Click"/>
<MenuItem Name="beat16" Header="16" Click="MenuBeats_Click"/>
</MenuItem>
<MenuItem Header="Beat Type">
<MenuItem Name="Whole" Header="Whole" Click="MenuBeatType_Click"/>
<MenuItem Name ="Half" Header="Half" Click="MenuBeatType_Click"/>
<MenuItem Name ="Quarter" Header="Quarter" Click="MenuBeatType_Click"/>
<MenuItem Name ="Eighth" Header="Eighth" Click="MenuBeatType_Click"/>
<MenuItem Name ="Sixteenth" Header="Sixteenth" Click="MenuBeatType_Click"/>
</MenuItem>
</ContextMenu>
</Image.ContextMenu>
</Image>
</Canvas>
An other option is to get the context menu from the image.
var items = Options.ContextMenu.Items
foreach(MenuItem item in items)
{
// do your work with the item
}
Be arware that you will have to handle the sub items!
Items will have only 2 items in your case
You have incorrect markup. Last two symbols shouldn't be there:
<MenuItem Name="beat8" Header="8" Click="MenuBeats_Click"/>/>
However, you example perfectly works for me, but with accidental item:
"/>"
Just in the constructor of the class in code behind write NameScope.SetNameScope(contextMenu, NameScope.GetNameScope(this)); contextMenu is the name given to context menu of image. Actually ContextMenu is not the part of Visual tree so it cant find the names . but the above line of code will set context menu in the scope of visual tree and hence will find the names. Hope this will help.

Categories

Resources