Alterning default Menu(Item) mouse reactions - c#

I am making a customized menu, with customized menu Items. Changing control templates and styles have been oke, but now I would like to change the way mouse events effect the menuItems visibility.
By default, when you click a MenuItem within the pop up of a parent menu item, the pop up will collapse. When the mouse leaves the pop up stays open. I would like to reverse this, so that the pop up would only collapse when the mouse leaves, and that a sub menu Item can be clicked multiple times sequentially.
Is this possible ? and ifso how could I be able to do this ?
Any information providing me with more insight, or leading to a solution is welcome!
Thanks

Use StaysOpenOnClick property on menuitems to keep the menu open on click.
A menu will close when it looses focus which is fine for me. If you want to automatically close the menu when the mouse is no longer on it you need to do this in code behind. Below code does this for the main menu by checking when the mouse is outside the area of the context menu. It only works for a menu with no submenu. If you want to use submenus you need to figure out when the mouse is over a sub menu and when not.
<Window x:Class="MenuTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid Background="Red">
<Grid.ContextMenu>
<ContextMenu MouseMove="ContextMenu_MouseMove">
<MenuItem Header="Menu Item" StaysOpenOnClick="True" />
<MenuItem Header="Menu Item" StaysOpenOnClick="True" />
<MenuItem Header="SubMenu">
<MenuItem Header="Menu Item" StaysOpenOnClick="True" />
</MenuItem>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</Window>
Event handler:
private void ContextMenu_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
ContextMenu contextMenu = sender as ContextMenu;
Point p = e.GetPosition(contextMenu);
contextMenu.IsOpen = p.X >= 0 && p.X <= contextMenu.ActualWidth && p.Y >= 0 && p.Y <= contextMenu.ActualHeight;
}

Related

Using ContextMenu in TreeView

There is an application I want to make using C#. This is part of it's UI:
The white area below the menu bar represents a TreeView. I want the Tree_View menu to appear everywhere in the white area when right-clicking with the mouse.
This is the XAML code for the Tree_View object (mind the foo function there):
<MenuItem Name="Menu_Tree" Header="_Tree_View">
<MenuItem Header="_New_Scene" IsCheckable="false" Click = foo/>
<MenuItem Header="_Copy_This_Scene" IsCheckable="false"/>
<MenuItem Header="_Remove_This_Scene" IsCheckable="false"/>
<Separator />
<MenuItem Header="_New_Shot" IsCheckable="false"/>
<MenuItem Header="_Copy_This_Shot" IsCheckable="false"/>
<MenuItem Header="_Remove_This_Shot" IsCheckable="false"/>
<Separator />
<MenuItem Header="_Move_This_Shot_Up" IsCheckable="false"/>
<MenuItem Header="_Move_This_Shot_Down" IsCheckable="false"/>
</MenuItem>
and this is the XAML code for the Tree_View object:
<Grid Name="TreeHolder" Column="0" Margin="20,10,10,10" Background="DimGray">
<TreeView Name="myTree" MouseRightButtonDown="something" ToolTip="Right Click to Add or Remove Scenes and Scots.">
</TreeView>
</Grid>
This is the something function which should be triggered by right-click:
private void something(object sender, MouseButtonEventArgs e)
{
ContextMenu cm = new ContextMenu();
//cm.Items.Add("Add a New Scene ?", ... );
Menu_Tree.ContextMenu = cm;
}
Since nothing works there, I want to ask the following:
a) How to make the Tree_view menu items appear in the Tree_View object white area as well?
b) If so, how will I make it an enabled menu, for example being able to trigger the foo function?
(In other worlds, make an exact copy of the menu list, make it visible with right click and make it work as well)
I strongly believe that it has to do with the ContextMenu which I am not able to use fairly, so any help would be highly appreciated.
The items to add are MenuItems. You can create each item as you would with any other object, set its Header property and assign a Click event handler. The sender is the TreeView itself.
private void something(object sender, MouseButtonEventArgs e)
{
var cm = new ContextMenu();
var newSceneMenuItem = new MenuItem { Header = "_New_Scene" };
newSceneMenuItem.Click += OnNewSceneClick;
cm.Items.Add(newSceneMenuItem);
var treeView = (TreeView) sender;
treeView.ContextMenu = cm;
}
private void OnNewSceneClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("I am a Message Box.", "New Scene clicked");
}
However, you can do this much easier in XAML without the right click handler.
<Grid Name="TreeHolder" Column="0" Margin="20,10,10,10" Background="DimGray">
<TreeView Name="myTree" ToolTip="Right Click to Add or Remove Scenes and Scots.">
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Header="_New_Scene" Click="foo"/>
<MenuItem Header="_Copy_This_Scene"/>
<MenuItem Header="_Remove_This_Scene"/>
<Separator />
<MenuItem Header="_New_Shot"/>
<MenuItem Header="_Copy_This_Shot"/>
<MenuItem Header="_Remove_This_Shot"/>
<Separator />
<MenuItem Header="_Move_This_Shot_Up"/>
<MenuItem Header="_Move_This_Shot_Down"/>
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
</Grid>
You do not need to set the IsCheckable to false, that is already the default value. Instead of assigning a Click event handler you could use commands, but I guess this would be a too advanced topic for you question, since it does not look like you are employing the MVVM pattern.

How to add to Click event to Context Menu buttons in WPF NotifyIcon?

I am making an app that has a notify icon in WPF. I am using HardCodet NotifyIcon. They do have a tutorial on code project and it is pretty useful but it does not have any explanation on how to set up OnClick or Click event when the buttons in the context menu are pressed.
I have gone through every property in NotifyIcon.ContextMenu.Items and NotifyIcon.ContextMenu.Items.GetItemAt(i) (TaskbarIcon NotifyIcon = (TaskbarIcon) FindResource("MyNotifyIcon")) but there is nothing I found. I also tried typecasting the buttons to MenuItem and using its Click event but it didn't help.
This is my App.xaml:
<Application.Resources>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tb="http://www.hardcodet.net/taskbar">
<tb:TaskbarIcon x:Key="MyNotifyIcon"
ToolTipText="Hello There">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu Background="White">
<MenuItem Header="Open"/>
<MenuItem Header="Settings"/>
<MenuItem Header="Sign Out"/>
<MenuItem Header="Help"/>
<MenuItem Header="Exit"/>
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
</ResourceDictionary>
</Application.Resources>
I need the buttons to control the MainWindow e.g. change the Visibility etc..
There is no difference to other controls, you can just set up a Click handler on each MenuItem.
<MenuItem Header="Open" Click="Open_OnClick"/>
In your example, you would implement the event handler in App.xaml.cs.
public partial class App : Application
{
// ...application code.
private void Open_OnClick(object sender, RoutedEventArgs e)
{
// ...do something.
}
}
You could also assign a view model as DataContext to TaskbarIcon and use a command instead.

WPF ContextMenu disappears when clicked

I have a WPF application and I added a ContextMenu for a grid. The user makes a selection on the grid and thereafter; a ContextMenu appears. I have some textboxes on the ContextMenu where the user can enter some values but if the user clicks the ContextMenu itself (and not inside the textbox) the dialog disappears. I want to prevent this and I tried to get some event that dictate when the ContextMenu has been clicked.
private void CreateContextMenu()
{
detectionInfoContextMenu = new ContextMenu(); //create an instance of the class
//selectionBoxCanvas.ContextMenu = detectionInfoContextMenu;
playVideoGrid.ContextMenu = detectionInfoContextMenu;
detectionInfoContextMenu.MouseDown += detectionInfoContextMenu_MouseDown;
}
void detectionInfoContextMenu_MouseDown(object sender, MouseButtonEventArgs e)
{
if(e.LeftButton == MouseButtonState.Pressed)
MessageBox.Show("You clicked me!");
}
I am trying to get the Mouse button events to determine if the Left mouse button was clicked. This seems to work very well on other control e.g. canvas etc but does not seem to work here on the ContextMenu. Am I using the wrong event?
You can use StaysOpenOnClick to prevent the closing of the menu:
<MenuItem StaysOpenOnClick="True">Test</MenuItem>
Or you use a Popup as Ivan Zub suggested in the comments.
And here an example with a TextBox inside the menu:
<ContextMenu>
<MenuItem StaysOpenOnClick="True">
<MenuItem.Header>
<TextBox Width="100" />
</MenuItem.Header>
</MenuItem>
</ContextMenu>

Context Menu Style not applied until right click

I have a context menu attached to a button on a toolbar on one of my controls in WPF (.NET 4.0). The context menu has a style assigned to it in the XAML that defines the context menu. Left clicking on the button opens the button's context menu if it isn't opened already.
Here's the relevant XAML:
<Button x:Name="fileButton" Foreground="White" Margin="7, 0, -3, 0" VerticalAlignment="Stretch" MaxHeight="70" MaxWidth="78" MinHeight="55" MinWidth="62" Style="{DynamicResource ImageButton}" utils:WpfImageUtil.Image="{StaticResource fileButton}" Template="{DynamicResource GlassButton}" Content="File" Visibility="Visible" Click="fileButton_Click">
<Button.ContextMenu>
<ContextMenu Style="{DynamicResource ContextMenuStyle}">
<MenuItem x:Name="saveMenuItem" Header="Save" Click="saveMenuItem_Click" Style="{DynamicResource MenuItemStyle}" />
<MenuItem x:Name="saveDrawingMenuItem" Header="Save Drawing" Click="saveMenuItem_Click" Style="{DynamicResource MenuItemStyle}" />
<MenuItem x:Name="openMenuItem" Header="Open" Style="{DynamicResource MenuItemStyle}">
<MenuItem x:Name="openFromFile" Header="From File" Style="{DynamicResource MenuItemStyle}" />
<MenuItem x:Name="openFromDesktop" Header="From Desktop" Style="{DynamicResource MenuItemStyle}" />
</MenuItem>
<MenuItem x:Name="iconsMenuItem" Header="Icons" ItemsSource="{Binding}" Style="{DynamicResource MenuItemStyle}"/>
<MenuItem x:Name="prefsMenuItem" Header="Preferences" Style="{DynamicResource MenuItemStyle}"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
ContextMenuStyle is defined in a resource dictionary that is properly referenced.
When the context menu is opened with a left click, the style I have defined isn't applied to the menu, as shown below:
However, if the user right-clicks and opens the context menu the traditional way, the style is applied as expected:
Afterwards, left-clicking the button will show the style correctly:
I have been trying to figure this out for some time, but haven't been able to come up with any reason that this issue occurs. It seems like some kind of bug to me, but I'm not entirely sure. I also don't know what happens at the lower level when controls are right-clicked on that would cause the style to get applied correctly.
You should assign ContextMenu Style property in code (FindResource method msdn):
private void fileButton_Click(object sender, RoutedEventArgs e)
{
if (fileButton.ContextMenu.Style == null)
fileButton.ContextMenu.Style = this.FindResource("ContextMenuStyle") as Style;
fileButton.ContextMenu.IsOpen = true;
}
ContextMenu Overview (http://msdn.microsoft.com/en-US/library/ms742558.aspx)
A ContextMenu is attached to a specific control. The ContextMenu
element enables you to present users with a list of items that specify
commands or options that are associated with a particular control, for
example, a Button. Users right-click the control to make the menu
appear. ...
When you right-click on the control, style will be applied to the ContextMenu. So if you want to open ContextMenu in code, you should check if style is equal null and if it's true, you should assign appropriate style.

Datagrid + Mouse right click event

I have a datagrid and it contains the list of files from the folder. I want to display the default window files right click options in right click on the filename.
That is when ever i right click the filename in the datagrid, a default windows right click pop up should appear.
Can anyone help me to sort this out. The project is in C#.
Thank you.
You should be able to add a Context menu to your data grid. The Context Menu will allow you to add in all the regular Windows right click menu options. The example below only shows copy, cut and paste.
<my:DataGrid
ItemsSource="{Binding}"...>
<my:DataGrid.ContextMenu>
<ContextMenu >
<MenuItem Command="Cut" />
<MenuItem Command="Copy" />
<MenuItem Command="Paste" />
</ContextMenu>
</my:DataGrid.ContextMenu>
</my:DataGrid>
You are able to add icons to the menu options as well if you'd like by writing the menu items more like this.
<MenuItem Command="Paste">
<MenuItem.Icon>
<Image Source="Images/paste.png" />
</MenuItem.Icon>
</MenuItem>

Categories

Resources