This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I am using WPF Elements 6 Enterprise (from the 2013-08-06 nightly build). My application allows users to set up an event that can take place anywhere in the world. The user may or may not be in the same time zone as the event. Client applications 'listen' for a notification when the event's start time is reached to automatically begin their processing. Internally, we store the event's startTime as a DateTime with the Kind property set to "Utc". Using UTC values for all internal calculations makes complex timing and coordination possible. However, users don't think in UTC; they are 'time zone aware,' though, and plan the event as starting at a particular date and time in a specific time zone. Users in different time zones may work on the same event, so when we display the startTime to the user, we always convert it from UTC to the event's time zone. To allow users to create an event and later edit the startTime, we display a dialog with a PropertyGrid control. A custom DateTimePropertyTypeEditor is used to edit the startTime property. Its DataTemplate consists of a Grid with cells for a DropDownDatePicker for the date portion and a DateTimePicker for the time of day. To deal with displaying the startTime as it would be in the event's time zone, I use a UTCtoTZConverter, which ensures that the source's DateTime value is always in UTC (with the Kind property set to "Utc") and DateTime value supplied to the DropDownDatePicker is always in the event's time zone (with the Kind property set to "Unspecified" if in any time zone other than "UTC" itself, in which case it is set to "Utc" by TimeZoneInfo.ConvertTime). This all works well until the user clicks the Today button in the DropDownDatePicker. When that happens, the value passed to the converter's ConvertBack is a DateTime with the Kind property always set to "Local". That causes the TimeZoneInfo.ConvertTime function to throw an exception because the supplied DateTime's Kind property does not match what is expected by the sourceTimeZone parameter ("Unspecified" for most time zones or "Utc" if the UTC time zone is selected.) The exception prevents the startTime from being updated, and puts the DropDownDatePicker control in an odd state; although the displayed date shows the date previously selected by the user, today's date appears selected on the Calendar if you drop it down again. (By the way, if we force users to always work only with the UTC time zone and do not use UTCtoTZConverter, the control always returns a DateTime with Kind set to "Utc" -- until the Today button is clicked in which case the Kind is "Local". That causes a problem because it updates the startTime with a value that is not UTC which in turn throws off all sorts of other calculations and conversion in the app.) There's another troubling side effect of this. If the event's time zone is UTC and the user is in a different time zone and if, at the moment the user clicks the Today button, the date in the UTC time zone happens to be different than the date in the user's time zone, then the DateTime returned by the control will be the user's current date -- not the current date for the UTC time zone. When that date is converted to UTC, it becomes the date of the previous day -- not the current day. Essentially that sets the startTime to the past -- and all our listening clients will begin their processing. This would happen, for example, if the current time is 1:00AM on a Monday morning in the UTC time zone which corresponds to 9:00PM on Sunday in the Eastern Standard Time zone. If a user in the EST zone clicks Today, the control it sets the stored UTC day to Sunday, which is actually the previous day there. There is a workaround for this that, while it works, should not be necessary. The DateTime provided to the ConvertBack function can be converted to one with the Kind set to "Uspecified" by using the DateTime.SpecifyKind() function. The result can then be converted to UTC using TimeZoneInfo.ConvertTime() without it throwing the exception. It would be most helpful if clicking the Today button returned a DateTime of the same Kind as the DateTime provided to the control. If the Kind is "Utc", clicking Today should return the current date in the UTC time zone, if Kind is "Local", then it should return the current date of the user's system (as it does now), and if it's "Unspecified" there's not much more you can do than return the current date of the user's system but with it's Kind set to "Unspecified". That would prevent the exceptions and resulting odd state of the control. (Also, other developers who want to keep the Kind of their stored properties consistent could do so without having to use a converter just to handle correcting the Kind for the case when the user clicks the Today button). A more complete -- and probably better -- fix would be to allow an option to specify the TimeZoneInfo to the control so it would have a context for understanding the DateTime it is working on and could use that to determine the date when the user clicked Today. I've attached a sample application that illustrates the problem and shows the workaround. DTEdit has an object, DT, that has a StartTime property the user can set using the PropertyGrid. The actual value of the StartTime property is displayed at the top of the main window. As the user selects different dates in the DropDownDatePicker control or clicks the Today button, the Kind property of the values passed to the conversion functions is displayed in Visual Studio's Output window. By commenting and uncommenting code in the MainWindow.xaml.cs and MainWindow.xaml files, you can see the effects of different combinations of event time zone (using UTC or Eastern Standard Time), using the converter, and/or using the workaround. On a side note, I've noticed that when the DropDownDatePicker control uses a custom format, there are 20 binding errors like these:
generated when the control loads. They all refer to Background or Foreground properties of TextBox or ComboBox items. (To see these in the sample, uncomment the last set of controls in the DataTemplate.) How can these be prevented? Thanks for your help, BillBR |
|
|
Hello BillBR Thanks for this suggestion and the repro project. For now I've gone with the idea of the Today button preserving the DateTimeKind. This will be updated in the next nightly build. Please give it a good kick around to make sure I haven't misunderstood the functionality. I've tried it in your repro project and the crash is resolved and the Today button functions consistently with the other MonthCalendar operations. Thanks for pointing out the binding errors. I believe these were only occurring in the Generic theme. This theme has not had as much care as the other themes. I've resolved this issue for the next nightly build. Please let me know if you come across similar issues in any of the other themes. Jason Fauchelle |
|
|
Thanks for the quick reply, Jason. While I think the option to allow developers to specify a time zone for the controls is preferable, I can live with at least preserving the DateTime.Kind for the return when the Today button is clicked. I'll download the next nightly build tomorrow and let you know what the result is. Regarding the binding errors, you're correct that I was seeing them in the Generic theme. I didn't have time to modify my sample to use the other themes, but I did try it on my real app. Alloy and AlloyLight worked fine, but I found similar problems in the others. OfficeBlack, OfficeSilver, and OfficeBlue all had 4 errors like:
Radium and Whalesong both had 56 errors like the others but including ItemsControls and on a DateTimePicker as well. Please note that my real app uses DropDownDatePicker/TimePicker in the DataTemplate for the startEvent editor. It also has an endEvent property on the same object, so the binding errors are coming from two pairs DropDownDatePicker/TimePicker controls. The number of errors above is probably double what it would be for a single control. You can get a better idea by modifying DTEdit to use the themes. Thanks, BillBR |
|
|
Thanks BillBR I've resolved all the binding errors that I have been able to reproduce with your project for all the office themes. This will be updated in the next nightly build. I'll leave Radium and Whalesong for now as these are example themes. Jason Fauchelle |
|
|
Works great with the nightly build of 08/29/13! Thanks for getting this to work, BillBR |
|