The bast way to track "modified" of a control? - wpf

I have a usercontrol which may contain many different kind of controls (e.g. button, textbox, combobox or checkbox). I need a generic way to track if anything has been changed. In most cases I don't care about the details (ie I don't need to know which textbox has changed). When I saw EventManager.RegisterClassEvent, I thought this would be my solution, but soon I realize it's not. This problem is that it's fired too much. For example, if I have a button and a combobox in the same control, the button.click event is also fired when I hit the combobox dropdown.
In WinForms, I had to loop through all controls in the usercontrol and subscribe to appropriate event (e.g. TextBox.TextChanged, or ComboBox.SelectedIndexChanged), it's tedious but works. I hope there is a better and easier way to do it in WPF.

Routed events:
<UserControl x:Class="..." TextBoxBase.TextChanged="UserControl_TextChanged"
Selector.SelectionChanged="UserControl_SelectionChanged"
ToggleButton.Checked="UserControl_Checked"
ButtonBase.Click="UserControl_Click" />

You can Put this checking to validate the e.source in the UserControl_Click event to handle this
If(e.Source.GetType()==typeof(Button))
{
// your code
}

Related

WPF Listview touch issue on window 10: "an event of another datatemplate is triggered while it may not happen"

When using a WPF application on windows 10 with a touchscreen we encounter an issue with the listview. When working with a mouse it works fine.
We have created a simple test-project, which is used to simulate the problem on windows 10 and can be found on GitHub. A ticket is also created on MSDN
In short below a summary of the technical setup:
We use a grouped listview, and for each group, a togglebutton and
another (inner) listview.
The inner listview uses an ItemTemplateSelector binded to an
Datatemplate selector, to choose an datatemplate.
There are 3 datatemplates (checkbox, numeric, text) that will be
choosen based upon the type property of the bounded model.
Each datatemplate has a stackpanel. The stackpanel in the text en
numeric datatemplate is wired to an PreviewMouseDown event.
Important, the stackpanel in the checkbox isn't wired to an event.
This works in general well, however sometimes, when touching the checkbox, the
PreviousMouseDown of another template is triggered.
I would expect that this behavior may not happen, is that correct?
We found a workaround (*) for this issue but we didn't find the root
cause.
Why is the event of another template triggered?
I'm starting to believe that this could be an issue with WPF Listview
and touch behavior?
(*) If we know that sometimes an event is triggered from a wrong template,
we verify every event whether that event is originated from the right template and if not we do nothing.
Below you can see when tapping quickly on the checkbox the clickevent get's triggered.
Below more details of the code:
The datatemplates and the selector
The grouped listview with the inner listview and the itemtemplate selector
Below the code behind and the handler for the PreviewMouseDown event
Below an overview of the steps we have been taken in order to resolve
it, but none lead into a solution.
Since WPF is supporting touch and a touch on a screen is also "translated" into a mousedown event, I don't see a problem why not using a previewMouseDown event on a touch screen. I also didn't find any offical documentation of Microsoft in not doing this.
Anyway, I could no longer reproduce the problem that a touch on listviewitem is invoking another previeuwMouseDown event of a template of another listviewitem in the list by ....
Changing the PrevieuwMouseDown event by a Touchdown event!
I am glad to find a solution, however based upon many online searches, I feel there are many issues with thouch on WPF and often it's is not clear what the rootcause is. Like in this case I found a solution by trial and error, but why the problem occurs when using previewMouseDown, is puzzling.

Setting Focus to a Control after the Loading of the DataGrid

I have a UserControl in WPF and it contains a variety of controls in it... The most important being the DataGrid Control. The DataGrid control is bound to an Observable Collection list. This list filled with different items based on couple of filters selected by the user. Now, once the DataGrid displays all the data. I want to set the Focus on the first (Filters) combobox on my usercontrol. Is there any way to know when the DataGrid has completely loaded??? Is there any DataTrigger I could set that i could trigger to inform me that Grid was refreshed with new list and I can set the ComboBox to focus. Basically i'm not able to set the focus to the first control on my UserControl when the data in the DataGrid has been repopulated... Please let me know if anyone knows how to resolve this issue!!
Thanks in advance.
I hate to work in code behind but sometimes that is only way. This can be done in two ways according to me:
Use EventAggregator to raise the event from your ViewModel once you are done with your filtering logic in it. Listen to this event in view code behind and in the handler do firstCombo.Focus()
Second is bit dirty, So there must be the button or the last control after which you apply filter on your listview. In the buttonClickHandler/or any event of the last control (like selectionchange) directly do firstCombo.Focus(). In this case the moment you will press your button focus will move to combo.
Thanks

wpf selecting controls inside a listbox

I have a textbox and some labels inside the data template of bounded listbox.
When I click on any label the whole item is highlighted in blue, but when I click directly on a different textbox the selection does not change.
Is there a way to make the selection of the listbox change even when a textbox is clicked?
thanks
This is what I've exactly asked few days ago, see post: "WPF: Trigger SelectedIndex changed whilst clicking on any control within a ListBoxItem area"
basically there are few solutions, using code behind and XAML, but I've not verified latter approach yet
The reason is because the TextBox handles the click event in order to receive focus. There are a number of ways to handle this, including but not limited to:
stop the TextBox handling mouse events (which prevents the user from focussing it using the mouse)
use an eventhandler when the TextBox gains focus (or PreviewClick or similar), to select the parent ListItem

WPF ListBox as RadioButtonList - mimic SelectionChanging Event via WPF validation

I am using ListBox for having RadioButtonList behaviour (that's what people recommend as there is no inherent radio button list in WPF). The listbox is bound to a ViewModel.
Now, whenever user changes the selection on listbox, I want to check whether user has some unsaved data on the part of screen and prompt accordingly (typical yes,no,cancel). If I use SelectionChanged event, the selection has already occured and hence, prompting is of no use. And there doesn't seem to be any SelectionChanging event.
I am am not sure but can I mimic SelectionChanging behaviour by using WPF binding validation rules?
Or should I use MouseButtonDown event? Would that lead to problems?
You don't need to put them in a listbox, the are group-able like so:
<RadioButton GroupName=“One“ IsChecked=“True“/>
Notice the GroupName, this holds the collection together, as for the rest of your question I am having a slight issue understanding what you need, sorry :(

How can I get WPF binding to occur on controls which have not yet been shown?

I have a custom text box control which raises a routed event when its TEXT property changes. This text property is data bound to a property on our view-model object.
When I place this control on a TabControl page or Expander control, it appears as if data binding only occurs when the control becomes visible for the first time, therefore I never receive any of the routed events until I swap to the tab the control is on or expand the expander.
Is there any way I can force data binding to occur before the control is shown?
Sounds like you relying on the data binding to genreate the routed event is the wrong approach. Instead you need to have your Model or ViewModel generate an event when the text is modified and then you watch this event from an appropriate place in your View.
Not very likely. WPF is a fairly efficient framework and won't do any work that it doesn't absolutely have to. This includes scenarios like data binding. Why bother exercising a collection for a control that might not ever be shown?

Resources