Reputation: 1202
I'm creating a WPF Custom Control.
The control is a time picker. It exists of a TextBox
containing a string representing the time the user inputs (like 16:35). When that TextBox is focussed, a Popup
opens, containing two separate TextBoxes for the hour and the minute for easy input.
The popup TextBoxes and the main field TextBox should be synchronized. By this I mean, when the user changes the hour by clicking the arrow keys, or typing in the small hour field, the main textbox (containing text 16:35) should be updated, and vice versa. The fields in the Popup are restricted to only accept [0-9] characters. When the main TextBox time string changes, string is parsed and the two fields in the Popup are updated. If the user types an invalid time string in the main TextBox and the control can not extract the hour and minute from it to update the Popup TextBoxes, then I just do nothing.
The arrow buttons in the popup are bound to commands.
I only use the class of the Custom control. I do not attach any DataContext and I only want to use dependency properties.
My control has multiple dependency properties, and the user-view that contains my control should use the following dependency property:
TimeSpan
For the internal working, I also have a few more dependency properties:
Hour
of type string (binding with hour TextBox in Popup)Minute
of type string (binding with minute TextBox in Popup)TextBoxText
of type string (binding with the main TextBox)Example of my problem:
When the user changes any field, the total control fields must be synchronized. So if the text in the hour field of the Popup changes, the main field's time string changes. I do this by using dependency property changed callbacks defined in the dependency property metadata. But the problem is that using this callbacks, you do not know if the change came from the control template (an action directly from the user) of from the class itself that sets a DP value). This causes vicious circles and you lose overview very soon. Its not that my program crashes, but problems occur like DP's are updated twice and that kind of unwanted behaviour.
How to solve this? Anyone who has experience with this or am I doing something wrong?
Upvotes: 2
Views: 237
Reputation: 17085
This is how I handle it most of the time:
pseudocode:
callback(){
if(flag){
it's coming from program
}
else{
it's coming from user
}
}
button_event_handler(){
flag = true
do_stuff()
flag = false
}
However there are other ways to do it if this is not applicable to your code.
For example in case of complex values like parts of date time, you can store the actual DateTime in a property which is bound to each of the controls through a converter. It must be injective or otherwise the whole thing will end up in a loop. By injective I mean each state of the updown controls must have only one state of the textbox and vice versa.
Upvotes: 1