WinForm text box: MenuStrip keyboard shortcuts overriding OS-level copy/paste - winforms

Update: I've figured out the source of the issue, now trying to figure out the best fix
I've got a Form with a customized MenuStrip, with all sorts of bells and whistles. Of note here, is that many of my MenuStrip items have keyboard shortcuts - namely ones for Cut/Copy/Paste.
It appears that the presence of this MenuStrip is overriding (and therefore cancelling) the default Cut/Copy/Paste keyboard shortcut behaviors for my text boxes (and other controls).
All of them.
.
I can't really say I have a reason for the MenuStrip Cut/Copy/Paste options, besides the fact that I would expect to see them there. That's how Office type programs operate, and it's something the user (myself included) would expect.
I could remove the Cut/Copy/Paste options from the MenuStrip, but that would be admitting defeat! So how do I keep my overly engineered MenuStrip from forcing me to implement custom code for EVERY control that's Cut/Copy/Paste friendly?
.
** Original Post: **I've got a TextBox control in a toolbar which is to be used throughout my program. Imagine my surprise when native OS-level Copy/Paste events were not supported by default.
Sure, I could code something manually, but when I right-click on the control, Cut/Copy/Paste are already built in. How can I leverage this existing functionality?
I figure adding a KeyDown event with Ctrl+C, P, and X would be about the maximum I should have to code. For those events I just call a built-in method or something. That, or find a setting that enables native cut/copy/paste.
What am I overlooking/missing?

Testing it out native copy and paste does work on a TextBox control unless you are overridding the ContextMenu or ContextMenuStrip, in that case you will need to use the ClipBoard Class to implement it yourself.
In looking at it further this MSDN Forum article discusses sending the Commands to the Native Textbox Control using the SendMessage Method. This is implemented in a Custom TextBox which sounds like what you are doing.
Small excerpt see article for further implementation:
protected void itemCut_Click(object sender, EventArgs e)
{
SendMessage(this.Handle, TextBoxMessages.WM_CUT, 0, 0);
}
public static class TextBoxMessages
{
public const int EM_UNDO = 0x00C7;
public const int WM_CUT = 0x0300;
public const int WM_COPY = 0x0301;
public const int WM_PASTE = 0x0302;
}

Easy Solution: Use the SendKeys.Send() call within the Click event.
SendKeys.Send("^X");
I'm doing something a little more complicated, so here's the details:
I'm making several Forms, which all share some custom controls: MenuStrip, StatusStrip, and a few other custom controls. I've decided to have the Forms all inherit from the same base class, to allow common implementation of lots of stuff.
public partial class CommonFormBase : Form
{
private void Initialize()
{
//Bind click event for custom MenuStrip to events in the local Form
CommonMenuStrip.Edit_Cut.Click += new EventHandler(Edit_Cut_Click);
CommonMenuStrip.Edit_Copy.Click += new EventHandler(Edit_Copy_Click);
CommonMenuStrip.Edit_Paste.Click += new EventHandler(Edit_Paste_Click);
}
//Implement Click events for the MenuStrip by calling local methods
internal void Edit_Cut_Click(object sender, EventArgs e) { Cut(); }
internal void Edit_Copy_Click(object sender, EventArgs e) { Copy(); }
internal void Edit_Paste_Click(object sender, EventArgs e) { Paste(); }
//Generic implementation of common commands for the CommonFormBase
public virtual void Cut() { SendKeys.Send("^X"); }
public virtual void Copy() { SendKeys.Send("^C"); }
public virtual void Paste() { SendKeys.Send("^V"); }
}
I implemented the MenuStrip's click event at the Form level (not the MenuStrip level), but in that event I only call a generic method, which does all the code. In this example it's overkill, but I have other MenuStrip commands that will change in functionality for different child Forms, so I figured having them all work the same would be easier.
Anyway, this works almost perfectly! It seems to push the shortcut-key-activated MenuStrip_Click event to the underlying control (or maybe the Form?), which then implements default shortcut key events.
The only thing it does wrong is it only triggers ONCE when you do Ctrl + V + V + V... or hold Ctrl+V. Still, that's just a matter of the trigger not recognizing multiple events, not an issue with the solution itself.

Related

Appropriate point to attach NodeChanged event, XAML

I've got a WPF usercontrol in a winforms application form.
Basically, I want a generic eventhandler attached to my WPF TreeView to handle "Document.NodeChanged". As this particular event fires when the tree is populated, I attempted to do a late attachment, via my treeview control's Loaded event.
The code goes something like:
private void UpdateGrid()
{
myGridView.UpdateXML(entityId, runDate, rtbToggleFullView.ToggleState == Telerik.WinControls.Enumerations.ToggleState.Off, userName);
//Safely attach the event to fire when the treeview has finished loading.
myGridView.tvRatings.Loaded -= AttachNodeChangedEvent;
myGridView.tvRatings.Loaded += AttachNodeChangedEvent;
}
Then the "AttachNodeChangedEvent" method looks like this:
public void AttachNodeChangedEvent(object i, EventArgs a)
{
((XmlDataProvider)myGridView.dataProvider).Document.NodeChanged -= OnNodeChanged;
((XmlDataProvider)myGridView.dataProvider).Document.NodeChanged += OnNodeChanged;
}
With a simple OnNodeChanged method:
public void OnNodeChanged(object i, EventArgs a)
{
Dirty = true;
}
The idea being:-
UpdateGrid runs UpdatesXML on treeview
Attaches a "NodeChangeHandler attacher" to treeview.Loaded
(when treeview is loaded) treeview fires "NodeChangeHandler attacher" which then attaches "OnNodeChanged" to the Treeview's populated XmlDocumentProvider.
This appeared to work perfectly in Windows 7. In Windows XP, however, the AttachNodeChangedEvent routine fires, and experiences a NullReferenceException (presumably because the Document hasn't loaded yet?) crashing the app.
Commenting out the ...((XmlDataProvider)myGridView... lines fixes the crash, but obviously disables the functionality.
Can anyone suggest a better way of achieving the same, or shed some light on why this works for Windows 7, but not Windows XP? "e.g. Attach NodeChangedEvent after the initial population of the Treeview"
I can confirm that both use the appropriate .Net Framework 4 package and seem to have all other dependencies appropriately included.
Thanks!

WPF UI Scenario - Best way to add a functionality in 50 views?

I want some suggestions to implement this functionality with a neat design and without any code replication. I have an application with many views and grid control in most of the views. I need to add an export functionality (export records to excel).The grid control supports this OOB, just need to call 'Grid.Export()'. I am planning a UI button on the side of every grid and call this method.
So, obviously I need to write the code in code-behind only since I need the control's instance to invoke the method. But, I like to keep the code in one place and somehow invoke the code from all Xamls. (all WPF views).
One technique is to write a BaseView class and derive all Views from this.
But would like to know if WPF suppots any techniques by which I can achieve this. (behaviours etc..?)
Thanks,
Mani
Create a UserControl that includes both the datagrid and the export button. In effect, make it part of the grid itself.
Use this UserControl instead of the default datagrid in all of your views, and you're done.
Furthermore, if you ever have to modify the look and feel of your button or its behaviour, you have only one place in which to change it, and it will be updated in all of your views.
One of solutions is to use WPF routed command.
Note: I wrote this answer with the assumption that your "View" is a subclass of Window class.
First, add a custom routed command to your project.
public static class MyCommands
{
private static readonly RoutedUICommand exportCommand = new RoutedUICommand("description", "Export", typeof(MyCommands));
public static RoutedUICommand ExportCommand
{
get
{
return exportCommand;
}
}
}
In each View, set your custom command to Button.Command and bind a target object to Button.CommandTarget.
<Button Command="local:MyCommands.ExportCommand" CommandTarget="{Binding ElementName=dataGrid1}">Export</Button>
Firnally, in your Application class (named App by default), register a command binding between your custom command and Window.
public partial class App : Application
{
public App()
{
var binding = new CommandBinding(MyCommands.ExportCommand, Export, CanExport);
CommandManager.RegisterClassCommandBinding(typeof(Window), binding);
}
private void Export(object sender, ExecutedRoutedEventArgs e)
{
// e.Source refers to the object is bound to Button.CommandTarget.
var dataGrid = (DataGrid)e.Source;
// Export data.
}
private void CanExport(object sender, CanExecuteRoutedEventArgs e)
{
// Assign true to e.CanExecute if your application can export data.
e.CanExecute = true;
}
}
Now, App.Export is invoked when user click a button.
Sample is available here.

Easy way to make Silverlight combo boxes perform like HTML select boxes?

I'm fairly new to Silverlight but experienced in web development, and I'm finding myself highly annoyed with Silverlight's default combobox. It seems to be lacking any concept of use for regular data entry. Primarily I'm wishing it would function like an HTML select box, where you can hit the drop down, then type a letter and it takes you down to the first item with that letter. Is there an easy way I'm missing to make it function like this, or a third party control that can do this?
Thanks!
You could write an attached behavior to provide this functionality. The problem is that the items in a ComboBox in Silverlight aren't always strings. They may be entire controls that the user has templated as the ItemTemplate. If you know yours are going to be string you can implement a Behavior<ComboBox> to attach to the KeyDown event and select the correct one.
public class HTMLSelectBehavior : Behavior<ComboBox>
{
protected override void OnAttached()
{
AssociatedObject.KeyDown += OnKeyDown;
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
SelectedItem = AssociatedObject.ItemsSource
.FirstOrDefault(i => i.ToString().BeginsWith((char)e.Key));
}
}
This is off the top of my head so it may not be exactly right and definitely lacks many safety checks, but it should give you an idea.

load event not fired in inherited user control loaded from another assembly (Winforms)

I have an application with plugin-like structure.
all application forms inherit from a base UserControl :
public class BaseUserControl : UserControl
{
// some common properties and methods
//
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
}
and are compiled in different assemblies.
When I want to show a form, it goes through this sequence:
assembly = Assembly.LoadFile(assemblypath);
.
.
frm = (BaseUserControl)assembly.CreateInstance(frmname);
.
.
SomeContainer.Controls.Add(frm);
MainScreen.Controls.Add(SomeContainer);
Common structure of these forms is :
public class TestForm : BaseUserControl {
public TestForm(){InitializeComponent();}
private void InitializeComponent(){
.
.
this.Load += new System.EventHandler(this.TestForm_Load);
.
}
private void TestForm_Load(object sender, EventArgs e){}
}
The problem is that the Load event of these forms does not get fired.
Another behavior, I don't understand how, when setting a break point at the OnLoad in the base class, the call stack shows that is called from within the InitializeComponent.
Any ideas on how to solve this?
You are hopelessly mixing up the terms Form and UserControl, making it very hard to give a good answer. They are very different beasts, you can't turn a UC into a form. It is a client window, not a top-level window. I suspect that has something to do with your problem but the generic diagnostic is that somebody is overriding OnLoad and not calling base.OnLoad().
Yes, OnLoad may be called from code in InitializeComponent(). It isn't very healthy since OnLoad will run before the constructor is finished, but it is supported. This will happen when you touch a property that requires the Handle to be created. The call stack should show you which particular property assignment did this, just double-click the line in the call stack.

Custom WPF command pattern example

I've done some WPF programing and one thing I never got was the command pattern. Every example seems to be for built in ones, edit, cut, paste. Anyone have an example or suggestion of best practice for custom commands?
Ah ha! A question I can answer! Firstly, I should mention that I have personally found it easier to define and hook up commands in code rather than in XAML. It allows me to hook up the handlers for the commands a little more flexibly than an all XAML approach does.
You should work out what commands you want to have and what they relate to. In my application, I currently have a class for defining important application commands like so:
public static class CommandBank
{
/// Command definition for Closing a window
public static RoutedUICommand CloseWindow { get; private set; }
/// Static private constructor, sets up all application wide commands.
static CommandBank()
{
CloseWindow = new RoutedUICommand();
CloseWindow.InputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt));
// ...
}
Now, because I wanted to keep the code all together, using a code only approach to Commands lets me put the following methods in the class above:
/// Closes the window provided as a parameter
public static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e)
{
((Window)e.Parameter).Close();
}
/// Allows a Command to execute if the CommandParameter is not a null value
public static void CanExecuteIfParameterIsNotNull(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = e.Parameter != null;
e.Handled = true;
}
The second method there can even be shared with other Commands without me having to repeat it all over the place.
Once you have defined the commands like this, you can add them to any piece of UI. In the following, once the Window has Loaded, I add command bindings to both the Window and MenuItem and then add an input binding to the Window using a loop to do this for all command bindings. The parameter that is passed is the Window its self so the code above knows what Window to try and close.
public partial class SimpleWindow : Window
{
private void WindowLoaded(object sender, RoutedEventArgs e)
{
// ...
this.CommandBindings.Add(
new CommandBinding(
CommandBank.CloseWindow,
CommandBank.CloseWindowExecute,
CommandBank.CanExecuteIfParameterIsNotNull));
foreach (CommandBinding binding in this.CommandBindings)
{
RoutedCommand command = (RoutedCommand)binding.Command;
if (command.InputGestures.Count > 0)
{
foreach (InputGesture gesture in command.InputGestures)
{
var iBind = new InputBinding(command, gesture);
iBind.CommandParameter = this;
this.InputBindings.Add(iBind);
}
}
}
// menuItemExit is defined in XAML
menuItemExit.Command = CommandBank.CloseWindow;
menuItemExit.CommandParameter = this;
// ...
}
// ....
}
I then also later have event handlers for the WindowClosing and WindowClosed events, I do recommend you make the actual implementation of commands as small and generic as possible. As in this case, I didn't try to put code that tries to stop the Window closing if there is unsaved data, I kept that code firmly inside the WindowClosing event.
Let me know if you have any follow up questions. :)
I blogged about a bunch of resources on WPF Commands along with an example last year at http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx
Pasting here:
Adam Nathan’s sample chapter on Important New Concepts in WPF: Commands
MSDN article: The Command Pattern In WPF
Keyvan Nayyeri: How to Add Commands to Custom WPF Control
Ian Griffiths: Avalon Input, Commands, and Handlers
Wikipedia: Command Pattern
MSDN Library: Commanding Overview
MSDN Library: CommandBinding Class
MSDN Library: Input and Commands How-to Topics
MSDN Library: EditingCommands Class
MSDN Library: MediaCommands Class
MSDN Library: ApplicationCommands Class
MSDN Library: NavigationCommands Class
MSDN Library: ComponentCommands Class
Also buried in the WPF SDK samples, there's a nice sample on RichTextBox editing which I've extended. You can find it here: RichTextEditor.zip
In the September 2008 edition of the MSDN magazine, Brian Noyes has a excellent article about the RoutedCommand/RoutedEvents!!!
Here is the link:
http://msdn.microsoft.com/en-us/magazine/cc785480.aspx
The thing about XAML is that it is fine for 'simple' programs, but sadly, it doesn't work well when you want to do things like share functions. Say you have several classes and UI's all of which had commands that were never disabled, you'd have to write a 'CanAlwaysExecute' method for each Window or UserControl! That's just not very DRY.
Having read several blogs and through trying several things, I've made the choice to make XAML purely about looks, styles, animation and triggers. All my hooking up of event handlers and commanding is now down in the code-behind. :)
Another gotcha by the way is Input binding, in order for them to be caught, focus must be on the object that contains the Input bindings. For example, to have a short cut you can use at any time (say, F1 to open help), that input binding must be set on the Window object, since that always has focus when your app is Active. Using the code method should make that easier, even when you start using UserControls which might want to add input bindings to their parent Window.

Resources