In a simple dialog app, using designer, I've set up the usual shortcut keys for cut, copy, paste and delete in the edit menu.
My problem is that I only want to handle delete events when a certain tree control is in focus. Otherwise, in my datagrid control for example, I want delete to work as usual.
What's the best way to do this? Currently I'm getting a delete event in the main form class, but the delete key isn't working in the edit controls in the datagrid control.
Edit - specified that the delete key isn't working in edit sub-controls
It seems that if you want to use the shortcut keys for menu items, that keycombination is taken throughout your form, no matter if you set up your eventhandler to not do anything unless a certain tree control is in focus (there is no way to set the key-event as .Handled=false).
So the best way would be to NOT set the shortcut-key in the menu-strip, but instead hook the KeyDown event on the form (keypreview) or on the specific tree control, and handle whatever the delete shortcut key should do there.
If you need the shortcut text to show even though you have no shortcut key defined in the menu-strip, use the .ShortcutKeyDisplayString property on the menu item to set a text.
If you're only going to have one form and only one datagrid,
the simplest method would be to fire off your datagrid delete events from the click event invoked by your menu item. Whichever row is current (bindingsource) or selected (datagrid), you can delete programmatically.
Related
I have an empty listbox which I would like to allow the user to paste items into. Currently I make sure the listbox has focus (as per WPF: How to enable a Command?) when the user clicks on it. Then if they right-click the context menu which contains the Paste command will be enabled and can be clicked which is excellent. However if instead of right-clicking the user presses CTRL+V on the keyboard the Paste command does not execute.
So far I can't figure out how to make this work. If the listbox has items in it and one of them is selected everything works fine.
Thanks
Add your own CommandBinding for the Paste-Command to the ListBox.
m_yourlistBoxReference.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste,YourExecutedHandler,YourCanExecuteHandler));
However, such as you already wrote, you have to ensure that the ListBox is focused, otherwise the CommandBinding will not execute. To ensure this, you can register to the PreviewMouseDown-event and focus the ListBox if not already IsFocused is true.
I'm not a WPF expert; however, in WinForms the easiest way is to add a context menu with the short-cut keys for Cut, Copy, Paste, etc. Then you don't have to do anything but implement the context menu click.
Is there any simple way to make a method that gets called whenever the user clicks out (or changes focus in some other way) from a text box in C#? I'm not really familiar with the way events are handled in C# - I rely on double-clicking a control to automatically generate the btn_Button_Click method.
Thanks!
Try Control.OnLostFocus, which occurs whenever the control loses focus.
You can get a list of events in the properties window for the control. If its not already visible, display the properties window from the view menu. Then select the control you want to add an event to, click the lightning bolt in the properties window (shows events) and add the event you need.
In my application I have dropdown list with several items. I'd like to show a context menu when the user clicks the right mouse button on a dropdown item. Is this possible? And if it is possible, how?
It is possible but not easy. The ComboBox dropdown is a native ListBox that is created on-the-fly. To get the handle of that list box, you have to send the CB_GETCOMBOBOXINFO message in the DropDown event. Check my answer in this thread to find out how to do this.
The iceberg that is likely to sink that Titanic is that the dropdown automatically closes as soon as it loses focus. Which will happen as soon as you display the context menu. Nothing you can do about that.
Consider a different approach, you could use an actual ListBox that you make visible when the user clicks a glyph that looks like an arrow next a TextBox.
Not possible easily. No hover or right-click event messages are being sent when the combobox is expanded.
You can see this is the case when using Spy++.
I think the easiest would be to change to a listbox if your scenario allows you to do that.
As Wim said in his post, there's not a direct way to do this because the messages you want aren't fired.
As a comprise, you could try setting DropdownStyle=Simple; on the Combo and
shrink the scroll region to show a single line:
http://img34.imageshack.us/img34/1695/49557147.jpg
If you assign the Combo a context menu, it will open when the scroll region is right-clicked. You'd probably have to figure out what item was right-clicked. But as other have said, this doesn't sound like a standard Windows way or an intuitive use.
Or how about a modal dialog that you could bring up from the Combo's context menu? On the dialog, you could have a list that the user could select from and a Delete button to delete the selected item(s).
Since MenuItem doesn't have a ContextMenu property it isn't as easy as it is with many other controls. You'll probably need to capture the right-click event and then position and show the context menu manually.
Two caveats though:
The combobox list will close when the
list loses focus, so it may close
when the context menu is shown
leaving the user unclear as to what
they clicked on (not 100% sure on
this, since I haven't written the
code to test.)
More importantly though I would argue
that this is a poor UI choice, I
can't think of any real world
applications I've used that have
context menus on menu items, so it
wouldn't be very discoverable for the
end user. Plus context menus should
be just for quick access, they
shouldn't be the only way to access
functionality. Are you going to be
able to expose these functions
through other means as well as the right-click menu?
You could do it manually, by capturing the event on the form, but consider making a nested menu instead. If your combobox items have menus of their own, combobox probably isn't the right choice.
For those asking "Why?" or saying they've never seen a combobox with a contextmenu; Look at any web browser's favorites dropdown. You can right click and delete, edit, or go to the entry in current tab, new tab, or new window.
I also could not get an actual contextmenustrip to show, so I made a menu with a small borderless form and call with:
Private Sub FavoritesBar_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles FavoritesBar.SelectedIndexChanged
FavIndex = FavoritesBar.SelectedIndex 'FavIndex is declared as a public string.
Dim Loc As Point = New Point(MousePosition)
FavMenu.Location = Loc
FavMenu.ShowDialog()
End Sub
With a homemade contextmenu, be sure to add "me.close" at the end of each sub as well as the me.mouseleave event.
I'm working on a custom user control that essentially displays a name value pair (name is on a black background, value on a white). I have my control displaying correctly, even showing up in Designer and on my build page.
What I'd like to do from here is have the ability to right click on the user control and have a menu come up that has a "Copy Value" option, that when selected will copy the value in the "value" part of the user control to the clipboard. What is the best method of approach?
I'm not sure where to start since most of the documentation on user controls I've found deals with displaying the control, not necessarily interacting with it. Additionally, since I'm still learning C#, I might have left out an important part of my problem in this question, so please point that out if it's the case.
I'm using Visual Studio 2008 (if that matters).
Examine the ContextMenu control and the ContextMenu property of other controls. By assigning a ContextMenu control to the ContextMeny property of another control, you will have the right-click->popup menu wiring done for you. Then you only need to implement the click event of the different menu items in the context menu.
Then you can use the Clipboard.SetText (as suggested by BFree) to set the desired value to the clipboard.
Add a ContextMenu to the control. The, hook into the MouseClick (or MouseDown, whichever works better) event and if it's a Right-Click, then call show on the ContextMenu (there are a few overloads, try to mess with them see which works best for you). Then, in the click event of your context menu, just call Clipboard.SetText(...) to set the value to the clipboard.
I have two tabitems. User will enter some data and save it on the first tab. The second tab lists the saved data. What I need is when the user select the second tab before saving data in first tab a confirmation message box with Yes, No and Cancel should be shown. If the user clicks Yes button the data should be saved and go to the second tab. If he hits No, the data need not to be saved and finally if Cancel is hit the tab will retain with all entered data. How can i make this?
To keep things simple you can do the follwing in the Code Behind file.
I'd create a Model class of the data you want to display and edit in the WPF Control. Make the Model implement the INotifyPropertyChanged and IEditableObject interfaces.
INotifyPropertyChanged will allow you to Bind to the Model.
IEditableObject will allow you to provide Edit, Save and Cancel functionality.
The TabControl has a SelectionChanged Event you can handle, that will allow you to detect when the user changes tabs, in this handler you can use System.Windows.MessageBox to ask the user to save etc, System.Windows.MessageBox.Show() returns a MessageBoxResult Object you can use to detirmine what button the user clicked and perform the appropiate action.
This is not a geat way to do things, but it keeps things simple, you may want to look into some WPF design Patterns to help with Code Manageability.
If you need anything explained further, just ask.
Although I disagree with the way you interrupt the user's flow from tab to tab I'm going to humor you and answer the question:
You'll need two things to get this done:
The event that occurs when a tab was clicked
The previous tab that was selected (the one you came from)
The first item:
The tab control has a Click method that you can subscribe to:
Click=”MyTabButton_Click”
The second item:
This part you'll have to do manually. You can set a variable in the click event which contains what tab was last selected. Once this is set you can check a variable (which you previously set) as to what tab was previously selected. You can then do all your validation.
Delphi's TPageControl has an OnChanging event with an "AllowChange" parameter. I guess there is something similar in WPF.