how to intercept winform textbox selection right click copy - winforms

I need to transform the copied selection in a winform textbox before copying to clipboard. I have the ctrl-c done, but the right click copy would seem to require overriding WinProc,and the link in an example in how to disable copy, Paste and delete features on a textbox using C# for WM_PASTE is no longer is valid. I would add failure may be a feature, because Ctrl-c could be transformed and right click copy could be the literal, both of which I need to do. I had hoped to radio button a state for a transformed or literal selection for choosing behavior.

My question was based on reading that the only way to do this was to handle a WM_COPY, but the better solution would be to implement a context menu strip for each text box as needed.
The right click context would then be handled by event handlers.

Related

WPF Avalon Edit Make text upper case

I am using C# WPF with Avalon Edit Text Box.
I am trying to make all of the text in the text box uppercase and I get an error with additional message 'No undo group should be open at this point'.
I am using the following code:
a.Text = a.Text.ToUpper();
where "a" is the AvalonEdit.TextEditor
Thank you.
Setting the TextEditor.Text property has the side-effect of clearing the undo stack (just as with the normal WPF TextBox). Clearing the undo stack is only allowed when there's no open undo group.
If you did not intend to clear the undo stack, use the methods on textEditor.Document instead to modify the document. You'll want to avoid replacing the whole text, because that would also reset the selection and caret position (after all, AvalonEdit can't know how your new text is related to the old text).
If you do want to clear the undo stack (e.g. you're switching the view to a different document), you'll have to figure out why an undo group is open. Most likely, your code is running from the event handler of an event that is called while the undo group is still open (e.g. document.TextChanged) -- you might want to switch to a different event instead (e.g. document.UpdateFinished is called after the undo group was closed).
If all you want to do is to upper-case text as it is being input, it's better to modify the text before it is added to the document: handle the TextArea.TextEntering event to cancel any lower-case input (set e.Handled = true;), and instead call TextArea.PerformTextInput() to repeat the text input process with the corresponding upper-case text instead.
For copy-paste, you could handle the attached DataObject.PastingEvent and modify the data to be pasted.

Maya drop down menu

I've got a pretty complex question for any Maya coders...
I want to utilize a drop down menu similar to that of the cmdScrollFieldExecuter's [script editor's] "Show Tooltip Help". It looks like a window that has been appended to the bottom of the inputted text with a feedback of all relative commands or strings.
Does anyone have experience with appending a similar textbox/ window/ menu to typed input, and if so, can you toss me in the right direction?
Note: I am not talking about "optionMenu".
Alternatively, is there a way to get cmdScrollFieldExecuter to reference a different array or set of strings?
A complete port of that won't be possible in vanilla Maya - You'd need to use python and QT because the built-in GUI objects (such as TextField) don't fire any events on keypresses so you won't be able to live-update as the user types.
You can almost fake the visual appearance with a window whose title bar is set to off. Use a formLayout to dock a TextScrollField inside it. You'll need to hack up some way of dismissing it since it won't have a close box -- you could put it on a timer or add an invisible button covering the whole thing which closed the window when clicked

Wpf update source trigger explicit on multiple textboxes when a button is clicked and command is executed. In MVVM scenario

I have a situation like this, I have a browse when I can double click an object and it opens in a form and then I am able to modify it (behind the scenes I am passing that object from one view model to another). Then I am able to modify its fields, however the textblock does it immediately, so I can see the fields changing before I press save changes, whats worse when I press cancel the modifications stay on the browse.
I know I have to tell all the textboxes to UpdateSourceTrigger explicit, but I cannot find a simple example in an MVVM way, so only update when the button save is clicked and command associated with it is executed, that should force that explicit update on all texboxes. Any ideas how can I achieve it?
Thanks :)
You use magic. Or, you send a copy of the model, then wait for an OK, and on OK copy the values back to the original. Then you do a little dance and drink a little water.

Databinding falls behind event notification - discussion

Found an interesting problem that I first found in WinForms, and found again in Silverlight, and more than likely WPF as well when it comes to databinding.
I have a tab control with several tabs. As users click across the tabs, each time should be valid before allowing the user to switch from the tab.
For example, user is in a text box which is updated. Binding of text boxes is not flushed until the control loses focus. Loss of focus occurs when the cursor is moved from the control, and focus is given to another control.
In this scenario, the user tabs into a control (let's use text box for this example), and updates the text box. At this point the databinding has not flushed the control, and hence the VM has not yet seen the change. The user then uses their mouse to click the next tab of the control.
At this point things get interesting. I used the PreviewSelectionChanged (Telerik RadTabControl), as I want to check things out before the jump to the next tab occurs, and it also gives me the ability to cancel the event.
However, when I look at the VM, in this event, it still does not have the updated data. I see the VM is clean, and go ahead and allow the jump to the next tab.
As soon as this event is over however, the databindings flush, and the VM gets updated. what now? The events are out of sync! When the mouse was used to click the next tab, the textbox should have lost focus, flushed it's bindings, before the Preview of the Tab click! It's to late to jump back and say oops we didn't catch that in time!
I think I found an interesting work around to this issue - but I'm not 100% sure it will work 100% of the time. I cancel the current event, but then I use the Dispatcher and create a delegate pointing to another method with the same signature as the current event. The Dispatcher will add this message to the message pump, which by this time will now (hopefully?) be behind the messages of the VM updating...
My two questions are:
1) I'm assuming that the textbox control either didn't flush when the mouse left the control, or the process that was fired was too slow and hence the preview message was on the pump before the databinding - either way I see this to be a major issue.
2) Is the workaround a good solution?
Ok, first to answer question 1:
Just because the mouse left the textbox area, doesn't mean that the textbox lost focus. It only loses focus once something else gets focus. For example, if you moved the mouse out of the textbox and click on some other control on your page (it can be anything from a scroll viewer to another textbox, etc.) then your textbox will lose focus.
Now, based on that, the events do not happen in the wrong order. What happens is; your click event on the other tab triggers both the textbox to lose focus (and the data binding to take place) and the move to the next frame, and based on that, you basically get a race condition where the moving to the next tab happens before the databinding takes place.
About question 2:
What you can do is, set the UpdateSourceTrigger to Explicit, you will however be forced to then have some kind of text_changed event and manually update the binding.
You can read more about that here. It might not be the most complete explanation but is a good place to start.
On the other hand, you can associate some events to the textbox and force the textbox to lose focus on those events (e.g. mouse out).
Just an idea: Why not do everything in the VM's PropertyChanged event?
protected override void OnThisViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) {
if(e.PropertyName == "WhateverProperty") {
//Do your magic here for whatever you want to set
}
}
Have your TabItems bound to a collection that will control is being disabled or not.
<sdk:TabControl>
<sdk:TabItem IsEnabled="{Binding SomeProperty, Converter={AmIDisabledOrWhatConverter}}" />
</sdk:TabControl>
That way, everything is triggered whenever a property is chaned in the vm. No more timing issues since everything is on the vm.
Just my two cents.
There's a design defect here, and you're trying to work around the defect instead of fixing it. You shouldn't have to figure out how to cancel the Click event on the tab. The tab shouldn't be processing Click events in the first place.
Generally speaking, if it's not legal for the user to click on a control, the control shouldn't be enabled. The tab should be disabled until the state of the view model is valid.
Your view model should be exposing a command for navigating to the next tab, and the tab should be bound to the command. The command's CanExecute method should only return true when the state of the view model on the current tab is valid.
This doesn't fix your other problem, which is that Silverlight doesn't support UpdateSourceTrigger="PropertyChanged" out of the box. But that's a solved problem (here is one example).
Note that if you implement commands to handle this wizard-like navigation in your application, you can, down the road, change the view to use something other than a tab control (e.g. to use navigation buttons like an actual wizard, or something like Telerik's PanelBar) without having to screw around with event handlers.
Change your bindings to include UpdateSourceTrigger="PropertyChanged".
This will ensure that your data sources are updated on every key stroke, not just LostFocus.
MyOwnTextBox()
{
this.TextChanged += (s, e) => UpdateText();
}
private void UpdateText()
{
BindingExpression be = GetBindingExpression(TextProperty);
if (be != null && be.ParentBinding.Mode == BindingModes.TwoWay)
{
be.UpdateSource();
}
}
I am using this class it updates my binding on the fly, however there is issue with empty string and null values, if your destination property is nullable string then this will update empty string in your destination property. You can get workaround by using some sort of string converter which will use null instead of empty string in case of nullable strings.

Is there a way of undoing a selection a user makes with the combo box?

In WPF 3.5, is there a property of the combo box will allow the user to undo the selection they've made?
Code
If you look to a way to reset the selection from code (you wrote a property), try the following:
cboYourCombo.SelectedIndex=-1
or
cboYourCombo.SelectedItem=null;
Keyboard Shortcut
If you look for a keyboard shortcut to reset, I've never seen. But if you want, you can do it on your own, it's probably easy:
Attach an EventHandler to the PreviewKeyDown-event of your combobox (or register a general event-handler that works for all comboboxes in your window/app), check the key and if its the key you want to reset, use the code above to reset the selection. Please note, in the PreviewKeyDown-event you can also check for special-keys such as the control-key.
Provide an empty Value
However I think, better would be to add an empty entry and then preselect this empty value. If the user has changed the selection and wants to reset, he can select the empty value. Otherwise you change the standard UI-behaviour and not all people like this.
What do you mean by "undo"? Do you mean something like CTRL+Z (or an undo button), or something like CANCEL? Implementing true undo/ctrl+z on a combo box is something very few applications do, and it will surprise the user. This is a very bad idea, unless you have a very good reason.
If you have a very good reason to go against the design of most windows apps, you can add a handler for SelectionChanged, and implement your own history. Then, if the user either uses a keydown (ctrl+z), or clicks an "undo" button, you can set the selection yourself.
Alternately, if you don't really want an UNDO feature, and actually want a CANCEL feature (a common feature in UI apps), then you shouldn't worry about each control individually. Just keep a set of stored settings (in some custom class), and set all the controls back to the values that were stored. In the case of a combo box, you'd want to set the Selection property.

Resources