I have a request from a client to create a new interface for some proprietary scheduling data we have in our SQL database.
The requirements are as follows:
The scheduling data needs to be laid out in a calendar format to be able to be viewed 1 day/week/2 week/month at a time and be able to switch between these views.Inside each day there needs to be detail and summary data. That detail and summary data can consist of multiple rows (tasks) and columns of data, all of which could have a custom format (text/back color) applied to them.They also want to see something like a progress bar as a background of each row that shows the percent completion of each task (row).
I was wondering if I could use an UltraMonthViewMulti or a UltraMonthViewSingle as the primary calendar control for this, possibly inject 2 wingrids to get the rows & columns (with formatting ability), but I am not sure if it would be the right way to go, or truly even how to accomplish this.
I appreciate any help or suggestions in this matter.
Seradex
Hi Seradex,
There are a number of approaches you could take here. UltraMonthViewMulti only shows numbers and doesn't really have any space for data within a day. But it sounds like using UltraWeekView and UltramonthViewSingle would be good for your purposes.
Showing complex content inside a day isn't something these controls support out of the box, but it should be possible with a little clever coding. Your idea of using UltraWinGrids inside the day would be pretty simple to implement, but whether or not this is a good approach depends on how much content you intend to display at once. If you have 30 or more days visible at a time and each day has 2 WinGrids in it, that's 60 or more grids on-screen at once and that probably won't be very efficient. You are likely to run into some performance issues.
Another approach you might take is to simply generate an image for each day. You could write a method that creates a Bitmap and draws the data you want directly into it with whatever layout and formatting you want. Or you could skip the image and use a DrawFilter to draw directly into the control. Both of these approaches assume that the contents of the day don't have to be UI interactive, though. If the user needs to be able to click on a particular item within a day and have something happen, then this probably isn't the way to go.
Another approach would be to use a CreationFilter and embed one or more UIElements into the day. You can't realistically embed a WinGrid into the control in this way, but you could embed a FormattedTextUIElement which provides functionality similar to RichText or Html. Or you could add a bunch of TextUIElements and some ButtonUIElements, and of course, a ProgressBarUIElement. You could even create a UIElement of your own that contains some combination of these elements and then re-use it. This approach is obviously the most complex and requires the most coding, but it's also the most flexible and it should be efficient enough so as not to cause performance issues with your application.
In fact, even if you decide to go with the grid approach, it would probably be a good idea to use the CreationFilter to position the grid(s) inside the days.
Whatever approach you take, you will have to decide what to do if the information for one particular day doesn't fit within the available space. Do you want a scrollbar? Or a sort've "more info" button that shows the details? Either of those could be achieved with a CreationFilter, but the Scrollbar approach is trickier, as you need to somehow keep track of the scroll position of each day's list.
I can't see any reason why any of this would not be achievable, but it's not trivial and will require some coding. Of course, I'd be happy to help you out with any of these approaches.
I was just notified this afternoon that my requirements have actually been reduced due to one client re-evaluating their needs. They think they will be going in a different direction.
Basically I no longer need multiple columns of data per row as the few pieces I need could be concatenated together as long as I can associate that with an ID that I can use to refer back to my SQL data. I also no longer need any summary data in each day.Note that I did see based on your response that I might have been able to do the summary data from the old requirement by using a few text boxes and labels embedded below the grid, but since it is no longer needed it helps to simplify things.
I still need the text/back color and a progress bar behind (underlying) the row basically as if the text was in the progress bar. There will be no need to edit this text directly.This is basically to display the status of scheduled items and show when it is occurring. It will also be required to allow them to move an item (row/task) to a different day/time. I thought this would be the least challenging thing as I have done drag & drop with Infragistics before (within a wingrid) and could present them with a pop-up date-time control for precise control.
Also, you are probably right that I would need scroll bars as the client may have more things than can be displayed in each day.
Does either UltraWeekView or UltramonthViewSingle allow me to present a single day view and a 2 week view, or would I need a different base control for the day view and 2 UltraWeekViews for the 2 week view?
Basically the client wants to be able to simply & quickly switch between these views similar to within Outlook Calendar. The intended look is to be similar to an enhanced Outlook Calendar with the Day, Week, and Month (with High Detail) views. The two week view would either be like two Outlook Week views stacked on top of one another, or like the high detail Month View that only shows 2 weeks.
The other concern I had was speed as I once tried to implement your Windows Forms Gantt control using our custom data and it ended up taking over 10 minutes to load the data into the Gantt including all of the assignments, etc., and that was with much less data than what our clients typically have. I believe it was because I was unable to load everything via binding, and am hoping that when I return to this that I will be able to do binding using perhaps your WPF Gantt control - but this is off topic.Basically it is ok if the UI takes up to a minute to initialize, but each time frame's data must be loaded in very quickly.
Also, I completely expected that very little of this would be trivial (if anything).
I was wondering if these controls already have the ability to show a list of items similar to how Outlook does? Note that I have looked around in the documentation, but am having a hard time figuring it out with the short timeline I was given to come up with a design. Is there a sample project you could direct me to that illustrates the abilities it has as that could be very helpful. Note that development is not scheduled to begin until about two weeks from now.
I hope this was helpful to simplify and clarify things.
I greatly appreciate your assistance with this.
seradex said:The scrolling is not within the days of a Month type view in Outlook. It is when viewed in a Day or Single Week format. When viewed in the single week format in Outlook, the scrolling allows to scroll the entire week through the times of a day. Individual days cannot be scrolled. I have attached an image that shows this.
So that's easy. The screen shot you have here is basically an UltraDayView control with 7 days selected.
seradex said:Perhaps the look we want (the views) would best be accomplished using the UltraDayView and the UltraMonthViewSingle since the former can show up to two weeks which is what we want and the latter will show a month's view, especially because it sounds like the UltraDayView may show more data in a scrollable fashion which is what we want, and it seems like the UltraWeekView may have most of the same limitations that the UltraMonthViewSingle has.
Yes, that sounds right.
seradex said:I am glad to here that we do not have to load each control separately. I am surprised I didn't mention previously, but I hope we can load the data using binding as that is typically much faster than instantiating a new object for each task.
As I mentioned, the tasks are stored in the UltraCalendarInfo. Typically, you would create an UltraCalendarInfo component and put it on your form and then hook up the UltraDayView, UltraMonthViewSingle, UltraWeekView, and UltraMonthViewMulti to the same UltraCalendarInfo object so they all show the same data and are synchonized. The controls are designed to work together in this way. For example, if you select a range of dates in the UltraMonthViewMulti, this will automatically update the UltraDayView to show those dates. Just like in Outlook.
seradex said:You did not misunderstand what was desired with the scrolling. I did end up speaking with my contact today and he informed me that if it was too difficult, we could do without a scroll bar in each day when viewing in the month format. If we could simulate scrolling by having two buttons to 1. hide the topmost visible task in the day's list & 2. show the most recently hidden from that day's list, that would be great, but if we had to switch to an alternate view to see all of the tasks, then that would be acceptable (but not preferable).
If you use UltraDayView, then scrolling will not be a problem. It already supports this.
seradex said:I haven't had a chance to look at the samples, but plan to do so shortly. I recall that sometimes in the past for other things it was difficult to find a specific example that showed something like what we were trying to achieve.
The sample I mentioned previously should give you a good idea of how it all works. But if you have any questions, we are always happy to help.
It seems to me that the controls will work pretty much out of the box for you, except for the ProgressBar and possibly the extra data or styling you want to do for each task. You may need a CreationFilter or DrawFilter for this, and we can help you with that. It would help if you could create a screen shot with a mockup of how you want it to look. I'm not exactly sure at the moment how you want to reconcile the BackColor of the task with the ProgressBar.
Regarding DataBinding, the UltraCalendarInfo does support binding to a data source, but data binding does not generally carry with it any improvement in speed or performance. That's true in general, not just for these controls. The main advantages of binding are:
a) Less coding
b) The data is persisted in a database
I was finally able to review the samples and they look quite helpful. About the ProgressBar & the back color, I was originally thinking that the back color could have an alpha value in it so as to only partially obscure the progress bar, however, it may be that the progress bar is only required under one scenario, so we could probably get away with not setting a back color when the progress bar is displayed. The other possibility (if it can be done that is) would be to set the back color on the progress bar when that control is displayed instead of the task (appointment).
The reason behind using data binding for us is two-fold (beyond persisting the data). 1. Speed (In my attempt to use the Infragistics Win Gantt control, I found that manually creating each task was significantly slower than data binding, however that was needed because certain properties could not be handled via data binding) 2. A wingrid will also be connected to the data, and changes in each control must affect the other.
Also, with regards to the scrolling concerns, it would still be preferred to at least simulate scrolling in the Month View, similar to how all day events can be scrolled in the UltraDayView using the buttons (not the scroll bar), however, if it is determined to be too much during the development phase, then this requirement will be dropped. The same can be said about the Progress Bar requirement (if it is too much...).
That said, in my investigations with the samples I have not yet found how to handle a few things with the control. Of course the things one thinks would be easy, sometimes end up to be more difficult.
1. The only data we want to allow the user to modify is the start time. The duration and any other properties must not be able to be modified.
2. The user must not be able to manually add new appointments as well.
3. We want to detect and handle a double-click on a task/appointment so we can launch our own window. The alternative would be to display a custom context menu that includes our launch task, but is not the preferred method.
Also, is there a way with the UltraDayView control to hide the area with the times and display only the all day events area. This is not my preferred method, however it may be necessary to go this route, pretending that the appointments are all day events, instead of displaying the appointments at their actual times, based on the customer's final decision. I do realize however that this would cause some loss of control to schedule the appointment/task as the user would be unable to set the actual time from this calendar view. It would make no difference in the UltraMonthView as there does not appear to be any visible difference between all day tasks and those with a specific time.
Thank you for all of your help and I look forward to hearing from you.
Hi,
seradex said:I was finally able to review the samples and they look quite helpful. About the ProgressBar & the back color, I was originally thinking that the back color could have an alpha value in it so as to only partially obscure the progress bar, however, it may be that the progress bar is only required under one scenario, so we could probably get away with not setting a back color when the progress bar is displayed. The other possibility (if it can be done that is) would be to set the back color on the progress bar when that control is displayed instead of the task (appointment).
I can't see any reason why either of these approaches would not be possible. They would require some coding, of course. You will need a CreationFilter to embed the ProgressBar into the task in the first place. And it's certainly reasonable to change the ProgressBar's appearance, either in the CreationFilter itself, or if not, then using a DrawFilter. I haven't actually tried it, but I'm confident that it can be done with one small caveat - you can't use a CreationFilter to increase the size of the task. So the ProgressBar has to fit within the task.
seradex said:The reason behind using data binding for us is two-fold (beyond persisting the data). 1. Speed (In my attempt to use the Infragistics Win Gantt control, I found that manually creating each task was significantly slower than data binding, however that was needed because certain properties could not be handled via data binding) 2. A wingrid will also be connected to the data, and changes in each control must affect the other.
I can't see why that would be, unless you were adding each task and forcing the control to paint each time. It might be possible to improve the performance of adding tasks manually by using BeginUpdate/EndUpdate. But it's a moot point in light of #2.
seradex said:Also, with regards to the scrolling concerns, it would still be preferred to at least simulate scrolling in the Month View, similar to how all day events can be scrolled in the UltraDayView using the buttons (not the scroll bar), however, if it is determined to be too much during the development phase, then this requirement will be dropped. The same can be said about the Progress Bar requirement (if it is too much...).
As I said, scrolling within a day of a MonthView/WeekView would be very difficult and require a lot of coding. I believe it's probably possible to get this to work, but it's a large effort. For the ProgressBar and BackColor, I can easily whip up a sample to show you how to do those once you decide exactly what you need. But Scrolling inside a day might be beyond what we can reasonably provide a sample for via support. I could give you some direction and outline a basic approach to try, of course.
seradex said:1. The only data we want to allow the user to modify is the start time. The duration and any other properties must not be able to be modified.
There's nothing on the CalendarInfo for this, but what you can do is handle the events of each control and cancel the operations that allow user editing. For example, ultraDayView1_BeforeAppointmentResized, and ultraDayView1_BeforeAppointmentEdited. By setting e.Cancel to true in these events, it will prevent the user from dragging to resize an appointment and edit the text (subject) of that appointment, respectively. You might have to handle a few other events, and you will need to do this on an individual control basis (MonthViewSingle, WeekView, and DayView). I don't think MonthViewMulti has any editing capability, so that's not a problem.
seradex said: 2. The user must not be able to manually add new appointments as well. 3. We want to detect and handle a double-click on a task/appointment so we can launch our own window. The alternative would be to display a custom context menu that includes our launch task, but is not the preferred method.
These two essentially go together. What you do is handle ultraCalendarInfo1_BeforeDisplayAppointmentDialog (on the CalendarInfo). Set e.Cancel to true and show whatever dialog you want (or not).
seradex said:Also, is there a way with the UltraDayView control to hide the area with the times and display only the all day events area. This is not my preferred method, however it may be necessary to go this route, pretending that the appointments are all day events, instead of displaying the appointments at their actual times, based on the customer's final decision. I do realize however that this would cause some loss of control to schedule the appointment/task as the user would be unable to set the actual time from this calendar view. It would make no difference in the UltraMonthView as there does not appear to be any visible difference between all day tasks and those with a specific time.
You can set HideTimeSlotDescriptorArea on the UltraDayView to true.
Did a little more investigating and just wanted to add a couple more points:
1) There is a Locked property on the Appointment itself. So this will prevent all editing of the appointment across all controls. So you could use this and then expose some other UI for the user to change the start time.
2 + 3) There are properties on the Controls like AutoAppointmentCreate and AutoAppointmentDialog which can be set to false to prevent a double-click from automatically initiating these actions if you don't want to handle the events.
Mike, thank you very much for all of your assistance. You have been very helpful.
As for changing the date/time we envisioned the user would do so simply by dragging the appointment to a new slot, however this might conflict with the appointment being locked. If we have to unlock the appointment to enable this, then instead we may attempt faking the drag/drop of the appointment, or use your suggestion.
As for the scrolling the idea was to fake it, not to do real scrolling. Of course it may still be too much.
Thank you again.
Cool. Glad to hear it. :)
I just wanted to let you know that the information you provided was instrumental in achieving the desired goals. I managed to simulate the progress bar by manually drawing the back color for part of the appointment based on the percent complete of the task. I didn't require anything other than a static progress bar like indicator.
Loading an isl file is basically just another way of setting properties on the controls. Or, to be more precise, it's another way of resolving the values of those properties (since it doesn't actually set the property value in most cases).
So with a few rare exceptions, the isl doesn't let you do anything that the control doesn't already do. It's just a question of finding the right property to do it. :)
Thank you very much.
It appears that this was exactly the info was looking for. I wasn't planning to use an isl file in my application. I just couldn't figure out how to get it to do what I wanted.
Preventing it from loading the isl file and setting the ViewStyle to Office2007 appears to have done the trick.
Thank you very much for all of your help, it is most appreciated.
Just to clarify... are you planning to use IG.Isl in your application? This is an Isl file that we use for our samples, but there's no reason why you need to use it in your application. You could use a different isl included with the Infragistics suite, create your own isl, or use no isl. Is there some reason why you are assuming that you will be using the same isl in your app that the sample is using?
If you are not going to use this Isl, then you might want to comment out this line of code in the sample:
Infragistics.Win.AppStyling.StyleManager.Load(islFile)
This way, the Isl is not loaded at all and you will see how the controls look without it.
At that point, you could either try to create an isl that gives you the look you want or try to get what you want via property settings in the application.
Anyway, regarding the 4 points you listed here, these all appear to be functions of the ViewStyle property. The ISL is setting the ViewStyle of the UltraDayView to Office2007. So you can either create an isl that does this or simply set the ViewStyle to Office2007 in code. The ViewStyle is a property on the UltraCalendarLook which is a component that all of the Schedule controls attach to, similar to the UltraCalendarInfo. So it will affect all of the controls.
It might be possible to achieve these settings individually (without setting the ViewStyle), but I'm not absolutely sure. Presumably, it would be done via some other properties on the UltraCalendarLook. I could check into it, if you need it.