My question is similar to this: How to prevent ListBox.SelectedIndexChanged event?, but I want to ask it a different way.
Is there a simple way to determine if the 'SelectedIndexChanged' is coming from the user as opposed to initiated through code (e.g. ListBox.SelectedIndex = x)?
As far as I know, no, there's no simple way built-in. The best I've been able to do is set a flag just before changing it in code and then letting the event handler reset the flag and return.
I suppose you could start examining the call stack and see if it's originating somewhere in your own code or not, but I'm not sure how much it's worth the effort.
For me, the 'SelectionChangeCommitted' event was better suited for my purposes. It fires when a selection in the drop down is selected. This is the easiest way to handle the specific case when the end-user initiates the change. SelectedIndexChanged is to capture all cases.
Property change listeners don't distinguish between causes of a property change. It's a common problem. Setting a flag is the way to do it.
I do wish that there was a way to set values without firing property change events. But then, people argue that it breaks the whole object-oriented model, because it effectively allows you to change a field directly, without using a property.
Related
What is a quick way to reset all the Controls inside a panel to their initial states (Compile-time state)? I have TextBoxes, RadioButtons, ComboBoxes, and CheckBoxes to reset. I'd like them to reset to the values when the program first ran. I'd like a solution that does not involve looping or recursion mainly because I don't want to reimplement the same thing over again when I start witha new project. I'm simply finding a set of methods to call that will do the job. Are there any?
Your controls have no compile time state, because state is a runtime concept.
I think you mean you want controls re-initialized to the state as shown on your property sheets. This state is applied by the generated code located in InitializeComponent, so to re-apply that state, you could just call it again.
The only problem is InitializeComponent also wires up events, and you probably don't want to do that twice. You could possibly work around this by deregistering all of your events before calling it, or by deduplicating the invocation list afterward (see this answer).
I don't recommend any of this. The best approach would be to write your own method that sets the properties the way you want them, one by one. Sometimes ya gotta write code.
I am currently stuck on an issue that I have been unable to find an answer for. It involves 'overriding' built-in TextBox keyboard functions using MVVM. Here's my issue:
I have a TextBox that the users enters text into during runtime. I'm looking to implement keyboard shortcuts, or input bindings with this TextBox. I started out by using what seems to be the standard ICommand interface based approach, which I implemented simply as:
<TextBox.InputBindings>
<KeyBinding Key="Up" Command="{Binding testCommand}" Modifiers="Ctrl" />
</TextBox.InputBindings>
The idea is that I execute the command associated with the ICommand property as set in the ViewModel. However, the TextBox class already contains a baked in function for CTRL+UP which, as you may know, moves the caret to the beginning of the TextBox entry field. This function executes in addition to my Command, resulting in my desired changes, but also the caret moving.
Before MVVM, I would simply use the PreviewKeyDown event in Code-Behind, detecting the desired key combinations and using
e.Handled = true;
to stop the TextBox from firing its built in Command. This isn't an optimal solution, however, as it probably violates MVVM principles. It would also be difficult to implement in tandem with InputBindings declared in XAML.
During my research, I found an article that describes using a class provided by Blend that allows for executing a Command based off an event, potentially allowing me to listen for the PreviewKeyDown event, which fires before the built-in functions, but this would mean that I would not be declaring my key bindings in XAML, as the syntax does not seem to support keypress specific conditions, or InputBindings. I would have to do all key combination processing logic in the ViewModel, which seems like something the View should be doing.
Further research has led me to an interesting new area which involves intercepting and replacing certain 'ApplicationCommands' with a Command that always returns false on CanExecute, effectively removing the function. I was able to locate a case where someone wanted to replace the default CTRL+Z functionality. An abridged version of the full question shows the basic idea:
textBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo,
UndoCommand, CanUndoCommand));
Research of this ApplicationCommands class led me to a few other classes, one of which relates more directly to my issue: ComponentCommands. MSDN describes that class as containing (among other things)
ComponentCommands.MoveToHome
which would fit my Ctrl+Up command's built-in function. Using the syntax in the SO question I linked previously, I could theoretically prevent that command from executing, which is a step in the right direction. However, I'm hoping to make the key combinations that trigger my Command in my ViewModel customizable via ViewModel properties that the InputBindings would be bound to in XAML. If I implemented this approach, it would mean that I could not know ahead of time which built in functions might conflict with the user's chosen key bindings.
This was naturally resolved for me before I switched to MVVM by handling the arguments in the event handler in Code-Behind, as mentioned previously. Any key combinations I wrote into the PreviewKeyDown event handler that I had a special action for set the e.Handled to true, effectively preventing any possible built-in command that would follow once the method finished from executing after the event handler finished.
Is there some way I could implement this functionality, using InputBindings declared in XAML? What are my options?
Some ideas:
Perhaps I could expose the event handler for PreviewKeyDown on my TextBox, and inside the method I iterate through all of the TextBox's InputBindings, looking for provided key combinations that match the provided key press, and if found, I execute the associated command and set e.handled to true? I'm not familiar with manipulating InputBindings from Code-Behind, so I'm not sure how practical this would be, or if it would place too much load on the application (imagine a user holding down a key). It also seems a bit strange in terms of organization to set it up this way. I could see a situation happening where the input bindings fire twice.
I could also make a list of all the built-in commands that I'd want to always have around, even if the user set a key combination that conflicted, and disable the rest. That seems like a bad idea, as it would be quite laborious, and also could mess with something I couldn't anticipate.
Perhaps there's a way that I could calculate which built-in commands would conflict with the current input bindings and disable those, to be calculated each time the user sets the bindings?
I'm still learning MVVM and WPF, so I suspect that I may be missing something obvious or simply looking at it the wrong way. Any help would be greatly appreciated.
Edit:
It has been suggested that my question is a duplicate of this one. I have reviewed the answer and determined that the approach used is definitely a step in the right direction. I could use the attached object to implement the PreviewKeyDown handling without losing functionality of InputBindings in XAML. However, I do have some concerns.
It seems that the resolution was to move the InputBindings to the UserControl, and implement an attached object that would handle PreviewKeyDown. I have multiple TextBoxes in my UserControl which will need their own set of InputBindings, some of which would conflict with one another should they be moved to the UserControl level.
I can only conclude that the reason it was moved away from the TextBox was that the attached object could not be applied directly to the TextBox for some reason. If I was to attempt this, would I have to create some encompassing element that had the attached object that would hold each TextBox? Why can't the TextBox use the attached object itself?
Ok. This seems like an incredibly basic use case but fore some reason I am having an issue finding a common solution across control types.
Heres the use case:
A form is presented to the user with any editable controls. (Text box, combo, grid etc.).
The user edits a value in the control and tabs out.
Expectation is that I can wire to an event like Lost Focus and do "foo" with the changed value.
The user then gives focus back to the control and tabs out without making an edit.
Expectation is that whatever event I am wired to I can check if the value has been changed.
Is there one common event across controls that will only fire when the user has finished editing( such as tab out or enter ) and allow me to check previous state vs. current state?
Jason, you may want to look into Binding and DependencyProperties in WPF instead of tracking events in your form. You would bind a class to your form which exposes properties to be changed. Using DependancyProperties a single event is fired called "PropertyChanged".
Unfortunately is is a broad topic, but you will really get the full benefit of the WPF programming model. Searches on "dependency properties in wpf" will give you some good examples.
I think maybe this is Focus issue. There exist two different focus types: keyboard focus and logical focus. The the control that has keyboard focus is the one that has the caret, in what the user press a key and the control process that input. The a control may have the logical focus but not having the keyboard focus. Please check this in the MSDN article "Input Overview". About the other question, maybe you could process the TabControl.SelectedItemChanged for taking the event when a tab item selection changed.
Hope this is helpful to you...
What you may be interested in is implementing INotifyPropertyChanging (not just INotifyPropertyChanged).
As noted in the answer of this question, the INotifyPropertyChangING does not prevent you from changing a value, but to detect WHEN something DOES change, and what it's new value is going to be.
Hope it helps in your solution needs.
As the previous answers suggested, you would be better off by implementing a view - viewmodel structure, with your viewmodel having implemented INotifyPropertyChanged, and thus allowing you to bind to properties that will announce their changes to the UI.
If you don't want to do this, you can eventually subscribe on your input elements to the PreviewKeyUp event, check if the Tab key has been pressed and proceed from there.
What's the best place to implement validation logic code and conditional formatting code for a DataGridView?
In a lot of books and articles that I've read on this control, it seems to suggest that the appropriate event to handle for this is the CellValidating one.
Well, the name more than implies this as well.
However, this event triggers a bit too often for my tastes and I'm not sure it is required.
For example, this event triggers everytimes the users switches to another row.
On the other hand, the CellValueChanged event seems to trigger only when the value of the cell changes, which means the validation code runs only when the value changes and not everytime a user changes cells.
Now, since so many books use the CellValidating event, I wonder if there is not any gotcha (in display for example) with using the CellValueChanged?
I understand that the impact in performance should be irrelevant when using simple validation and conditional highlighting rules but I would as much prefer it not to run useless code everytime the user moves to another cell if it can be avoided.
Thanks,
I'm using CellValueChanged currently on a grid with custom validation and have had no problems with display or anything else.
I used this event because I wanted to fire off a certain order of events, but only when the user changes the value of a cell.
I have not noticed much in the way of a performance hit (tested with 100 - 5000 rows).
I think in the end it depends on what your validation needs are. In my case, CellValueChanged has done what I wanted/needed.
EDIT
The biggest thing about the CellValidating event is that you can stop the user from leaving a cell, if the value entered does not pass your validation. I didn't want to do this.
Its simple, inside the CellValidatingEvent you need to check if a condition is right. If your condition is false then you just add this code e.cancel. It will prevent the cursor to lost its focus
I have application full of various controls databound to my classes. I would like to ask user "You are closing application and you made some changes. Do you want to save your changes?". For this I need to recognize that user made any changes.
How to catch user made changes in databound controls? Is textBoxXXX_TextChanged the only way to do this?
Thanks in advance for all your answers.
It depends on the datasource; for example DataTable and DataSet sources contain the GetChanges() methods which allow you to easily see if rows have been added/removed/modified. Other data sources will have their own implementations, if any. If there is no implementation then it's up to you to determine how to check for those changes.
In any event this is something you should do at the data-level, not the UI (by watching for "changed" events). Watching events doesn't scale beyond a couple controls and maintenance can be iffy.
Update: Not sure why I didn't think of it, but a second option is to add a BindingSource to your UI object and use it as a databinding proxy (your UI controls databind to the BindingSource and the BindingSource binds to the real datasource). It provides a better approach than handling all your individual "Control_Changed" events, and requiring rework of your other layers (esp. if they aren't custom data-types).
You need to provide custom logic for that, there's not really an automatic way of doing this. As I see it there are several options:
At the start of the editing, save a copy of the original data object, and when you need to check, compare the current object with the saved one. The comparison can be custom (field by field) or semi-automatic by use of serialization (compare the serialized forms) - if it is serializable.
In each of your data object's property set accessors, test for a change in value and mark the object as 'dirty'.
As been discussed, there are many ways to do this depending on how granular you want to get.
A relatively easy way using client side javascript would be to do something like the following:
Hook into the onchange events of the form elements. You could do this dynamically on page load using javascript/DOM.
When the onchange error handler is called, you could set a page level variable: pageHasChanged = true;
Hook into the page's beforeonunload event (occurs when the user tries to navigate away from the page) and check the pageHasChanged variable to see if any changes were made. If changes were made you could alert the user.
This doesn't give you the detail of what changed, but would be fairly easy to modify to track which form elements changed.