One of the benefits of developing in WPF is the direct relation a developer and a designer now have. A designer can create styles and templates in XAML and the developer can easily tie back end code into that XAML all while both access the same code base. From a productivity value this is a huge win. As a WPF developer I have been through the hardships of receiving pictures or even flash demos where my task was to make the application real. Look, I know I am not a designer. I have spent many hours sizing up pixels, working on layouts, and skinning/re-skinning applications. However, I want to make things work, not make them look pretty…
That being said, even though I would like to work in the same environment as a designer and it makes overall development so much easier, there are some negative impacts. Most application code base has a promotion process. Different levels of testing environments before the code hits production. The one problem with styling and developing within the same code base is that a change to one item would result in re-compilation of the other. We still want to separate designer and developer responsibility even though we are in the same code base. Basically, re-skinning an application should have no effect on the application logic. For example, if a button color needs to be changed there is no reason why a recompilation of the event that button raises should occur. Alternatively, if the event process is changed there is no reason the recompilation of the style should occur.
One method of achieving this is through separating resources out into a separate project. By doing so, you can have a design promotion process along with a development promotion process where neither process is dependent on the others code being re-compiled. The style project contains all resources from layouts to animations. The code project has a configuration parameter in its App.config file which points to the styles DLL. In the example below I use a ConfigurationSection class in retrieving a configuration parameter pointing to a styles assembly.
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <configSections>
4: <section name="AppSettings" type="App.Module.AppSettings, App.Module"/>
5: </configSections>
6: <AppSettings
7: StylesUri="pack://application:,,,/App.Module.Styles;component/MainResource.xaml"/>
8: </configuration>
The above code in the App.Config file defines a configSection 'AppSettings’ of type App.Module.AppSettings in the assembly App.Module. The attribute in AppSettings is a URI containing some WPF packaging text, the style assembly, and the Main Resource Dictionary within the compiled styles DLL. I am assuming all styles in the project would be merged into a main resource dictionary for simplicity. Please refer to Pack URIs in Windows Presentation Foundation for more information on creating Pack URIs for resources.
1: using System;
2: using System.Configuration;
3:
4: namespace App.Module.AppSettings
5: {
6: public class AppSettings: ConfigurationSection
7: {
8: private static readonly AppSettings_settings = ConfigurationManager.GetSection("AppSettings") as AppSettings;
9:
10: public static AppSettingsSettings { get { return _settings; } }
11:
12: [ConfigurationProperty("StylesUri", IsRequired = true)]
13: public Uri StylesUri
14: {
15: get { return (Uri)this["StylesUri"]; }
16: set { this["StylesUri"] = value; }
17: }
18: }
19: }
My ConfigurationSection class defines the Styles parameter I can then use in code. One of the nice things about this class is that it enforces certain guidelines the attributes or elements in the AppSettings section in configuration must adhere to. For example, the StylesUri property must be of type URI. If you enter an integer for the StylesUri attribute in configuration, an exception will be thrown on loading of the application. Also, since isRequired is set to true, an exception will also be thrown if that attribute is missing in configuration. Again, the ConfigurationSection class enforces these rules so I do not have to write code against values in the configuration.
1: //load resource dictionaries
2: _view.Resources.MergedDictionaries.Add(new ResourceDictionary { Source = AppSettings.Settings.StylesUri });
Accessing the Configuration Section is quite easy as it is a singleton and can be accessed anywhere in the project. The line of code above loads the StylesUri value into the view’s resources.
In conclusion, there are several key benefits to external resources. First, designers and developers can still work in the same environment and code base yet not have direct implications on each other’s code. Second, from a developers perspective, this is a very clean implementation for handling styling within configuration. I do not have to worry about validating configuration parameters which is a huge weight off my chest and I do not need any knowledge of what the resources my application is styled to. Finally, this methodology introduces a really nice way for future re-styling without affecting the core code base. Lets say six months from now the look and feel of the application needs to change from a summer design to a winter. The core code base is never touched. The designer can adjust the styles accordingly, compile and update the code project configuration StylesUri.
A quick helper when dealing with WPF animations and CPU usage. By default, WPF animation frame rates run at 60 frames per second. However, the eye cannot tell the difference from anything above 30 frames per second. Obviously, more frames per second result in higher CPU utilization. For many animations running at 60 frames per second is overkill. However there is a way to change this value. By adding the line below at the start of your application, you will set the default frames per second for any animation to your desired value. In the case below, 30 frames per second.
1: Timeline.DesiredFrameRateProperty.OverrideMetadata
2: (typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = 30 });
After this is set, all animations will run at 30 frames per second thereby decreasing your CPU utilization and improving your overall applications performance.
The WPF Line of Business seminar is a two day introductory provided by Microsoft outlining WPF, its benefits, architectural patterns practiced, and coding tips within line of business development. After developing in WPF for over a year I thought this would be a good seminar to attend to gage where I am at as far as WPF development. Well, I am very happy to find I follow very similar techniques and patterns as the Microsoft WPF experts Karl Shifflett and Jaime Rodriguez. The seminar took place on June 12th and 13th at the Sheraton in Arlington Heights, IL.
Well, I missed day one, which I don’t necessarily feel is bad for me. It went over very basic fundamentals of WPF and XAML. Below was the agenda I obviously missed.
Day One: - Lap Around WPF
- WPF Tools ( Blend, Visual Studio 2008)
- Graphics Subsystem
- Layout
- WPF Fundamentals and new concepts
- Application Model
- Dependency Properties
- Trees (logical & visual)
- Events
- Threading
- Resources
- Controls
- Styling
- Templating
- Q&A with instructors at end of day
So I wasn’t even supposed to go to Day Two however mother nature helped me out. I had a baseball game at a minor league stadium, didn’t really want to miss that even if it would give me the opportunity to meet Karl Shifflett. But rain washed that away and I went to Day Two. Of course, I was late. You can’t blame me. 9:00 on a Saturday morning in a suburb that is an hour away from the city and having five hours of sleep, well it was tough. Below is the agenda I actually took part in. Day Two: - WPF integration with Win32 and Windows Forms
- Data binding
- Introduction to Model-View-ViewModel
- Commanding in M-V-VM
- Views, Navigation and Transitions
- Data Validation
- Error handling, Model dialogs, Logging
- Unit Testing
- MVVM & LOB tips and tricks
- Q&A with the instructors
Karl Shifflett was the first presenter, and if you read my previous posts on XAML, I have been reading his blogs for a long time and can say they have helped changed my perception of development in WPF. I am going to summarize what he talked about as I am extremely tired after a long day of listening…. Karl talked about Databinding and how powerful it is. Databinding is basically WPF 101. He then talked about specific XAML features such as DataTemplates, ControlTemplates, ItemTemplates, ItemsPresenter, ValueConverters, and DataTempleteSelectors. I love ValueConverters but you do have to be careful not to overuse them. Basically, you need to decide whether to create a ValueConverter or convert parameters within the View Model itself. My rule is if a converter is needed in multiple Views then it warrants a ValueConverter, however if it is a date conversion for a specific view, it should be placed in the View Model. He briefly talked about data triggers, which Jaime would later say shouldn’t be used. Sorry Jaime I would disagree with that statement. I believe there is a separation between Business Logic and Design Logic and Data Triggers are completely valid for Design Logic.
Here are some things I learned from Karl:
DataTemplateSelectors - I don’t think they are necessary. You are basically creating a resource outside your View-ViewModel relation and I feel that this can be contained within this relation view DataTemplates, binding, and DataTriggers.
CollectionViewSource – Represents a layer on top of the binding source collection. It allows sorting, filtering, and grouping of data before being displayed in a view. Very, very cool….
Debug of Data Binding – Karl talked about an interesting way to debug data binding a little further. By adding System.Diagnostics and Trace levels to a binding source the output can display more detailed information if a binding error occurred. Below is an example of how this can be implemented.
1: <Window
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
5:
6: <TextBox.Text>
7: <Binding Source="{StaticResource myDataSource}" Path="PersonName"
8: diag:PresentationTraceSources.TraceLevel="High"/>
9: </TextBox.Text>
Jaime Rodriguez was the next presenter and started his presentation giving an architectural perspective of the MVVM pattern. I was happy he gave props to Martin Fowler, one of the founding architects of this pattern. Jaime explained the concept of MVVM and the idea behind the separation between Views and Models. He also talked about the benefits of MVVM such as modularity, loosely coupled code, and testability.
Jaime next talked extensively about Commands. He discussed RelayCommands, DelegateCommands, and the DelegateCommand in the MVVM Tool kit. Commands are very important to binding in that they enable you to route events from Views to ViewModels. The benefit of this is that you do not have to write any code behind in the view and your business logic from a command is separate from your design. I have used RelayCommands and DelegateCommands in the past. Relay Commands use CommandManager which provides command related utility methods that register command bindings. DelegateCommands are part of PRISM, so to use DelegateCommands you need to add the Microsoft.Practices.Composite.dll. DelegateCommands in the MVVM Tool kit are quite interesting as you do not need a Command Manager nor the Microsoft.Practices.Composite.dll. I definitely have to play with this a little more.
Karl finished with some talk about Validation in WPF. Karl gave examples of when to use validation in XAML and when to apply validation to business layer development. He also talked about his Ocean Framework and validation using an AdornerElementPlaceHolder. AdornerElementPlaceHolders are used for custom validation templates to provide visual feedback when a user input is not valid. Basically, the add validation capabilities within XAML.
Well, I know this post is a little overdue as the seminar was a week and a half ago. But I finally am able to get it out there. If you need more information about Jaime and Karl you can view their respective blogs, Jaime, and Karl. They both have information about the WPF LOB seminar in Chicago which includes demos and slides.
Animations are a feature in WPF and Silverlight that greatly enhance the user experience of the application. Animations provide a smooth transition from one scene or view to the next and can significantly improve the overall composition and flow of that application. Animations in WPF, currently are time based which means an animation will start and stop based on your computer system clock. This, at times, could be an issue if your processor is experiencing excessive usage, your animation might skip frames thus resulting in choppy and less fluid animations.
In XAML, animations are created using a storyboards which can either be defined in XAML or code behind. Please refer to the MSDN explanation of animations for more of an introductory. This post details when it is a good time to create a storyboard as a resource in XAML and when it is more beneficial to create a storyboard in code behind.
XAML Storyboards
For most cases, such as dealing with opacity, brush, or simplistic transform animations, storyboards can and should be created in XAML. Below is a simple example of a storyboard that animates the three parts described.
1: <Storyboard x:Key="LoadAnimation">
2: <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
3: <SplineDoubleKeyFrame KeySpline="0,0,0,1" KeyTime="00:00:00" Value="0.5"/>
4: <SplineDoubleKeyFrame KeySpline="0.782,0,0,1" KeyTime="00:00:00.3000000" Value="1.1"/>
5: <SplineDoubleKeyFrame KeySpline="0,0,0,1" KeyTime="00:00:00.6000000" Value="1"/>
6: </DoubleAnimationUsingKeyFrames>
7: <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
8: <SplineDoubleKeyFrame KeySpline="0,0,0,1" KeyTime="00:00:00" Value="0.75"/>
9: <SplineDoubleKeyFrame KeySpline="0.782,0,0,1" KeyTime="00:00:00.3000000" Value="1.1"/>
10: <SplineDoubleKeyFrame KeySpline="0,0,0,1" KeyTime="00:00:00.6000000" Value="1"/>
11: </DoubleAnimationUsingKeyFrames>
12: <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="txtTitle" Storyboard.TargetProperty="(UIElement.Opacity)">
13: <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" KeySpline="1,0,1,1"/>
14: <SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="1" KeySpline="1,0,1,1"/>
15: <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
16: <SplineColorKeyFrame KeyTime="00:00:00" Value="#CC333333"/>
17: <SplineColorKeyFrame KeyTime="00:00:00.4000000" Value="Black"/>
18: </ColorAnimationUsingKeyFrames>
19: </Storyboard>
Now if you remember from my previous blog, Resource Dictionaries Vs. User Control Resources, this resource can either be in a resource dictionary that all XAML files can have access to or in a specific User Controls resource. My example above is actually taken from a Resource Dictionary because I have multiple views load using this animation.
Code-Behind Storyboards
So when is it a good time to create code behind storyboards? Well, I have found it is easier to create storyboards in code behind when you are dealing with any sort of animation that requires run time decided parameters to be passed into it. That is not to say this cannot be achieved in XAML as well, but a rule I follow is that any logic determinant code should be in code behind, controllers, or view models. One thing to remember, code behind storyboards should be contained within some User control code behind itself or a base control code behind. A lot of people are moving towards the MV-VM pattern and a rule of thumb is that anything to do with design altering should be within the View and not the View Model. Below is an example on my application where I calculate the animation trajectory of an image.
1: private void BeginIndicatorAnimation()
2: {
3: Storyboard indicatorStoryboard = new Storyboard();
4:
5: _animatedImage = new Image();
6: _animatedImage.Source = _indicatoritems.IndicatorSmallImage;
7: _animatedImage.Height = 200;
8: _animatedImage.Width = 200;
9: _animatedImage.VerticalAlignment = VerticalAlignment.Top;
10: _animatedImage.HorizontalAlignment = HorizontalAlignment.Left;
11: _animatedImage.Margin = new Thickness(0, 0, 0, 0);
12:
13: Grid grid = (Grid)this.FindName("grid");
14: ConvertTargetToImage(grid);
15:
16: grid.Children.Add(_animatedImage);
17:
18: System.Windows.Markup.INameScope currentNameScope = NameScope.GetNameScope(this);
19: NameScope.SetNameScope(this, new NameScope());
20:
21: _animatedImage.Name = "adornLayer";
22: this.RegisterName(_animatedImage.Name, _animatedImage);
23:
24: TranslateTransform animatedTranslateTransform = new TranslateTransform();
25: this.RegisterName("AnimatedTranslateTransform", animatedTranslateTransform);
26:
27: ScaleTransform animatedScaleTransform = new ScaleTransform();
28: this.RegisterName("AnimatedScaleTransform", animatedScaleTransform);
29:
30: TransformGroup transformGroup = new TransformGroup();
31: transformGroup.Children.Add(animatedScaleTransform);
32: transformGroup.Children.Add(animatedTranslateTransform);
33:
34: _animatedImage.RenderTransformOrigin = new Point(0.5, 0.5);
35: _animatedImage.RenderTransform = transformGroup;
36:
37: //Create Animation Path
38: PathGeometry pathGeometry = new PathGeometry();
39: PathFigure pathFigure = new PathFigure();
40:
41: double x = (CurrentPosition.X - (_animatedImage.Width / 2));
42: double y = (CurrentPosition.Y - (_animatedImage.Height / 2));
43:
44: pathFigure.StartPoint = new Point(x, y);
45: pathFigure.Segments.Add(new LineSegment(new Point(980 - 120 * (_indicatoritems.MealIndicatorCount - ++_indicatoritems.CurrentIndex), 90), true));
46:
47: pathGeometry.Figures.Add(pathFigure);
48: pathGeometry.Freeze();
49:
50: //Create Animation
51: //Opactiy
52: DoubleAnimation opacityAnimation = new DoubleAnimation();
53: opacityAnimation.From = 1.0;
54: opacityAnimation.To = 0.0;
55: opacityAnimation.AccelerationRatio = 1.0;
56: opacityAnimation.Duration = new Duration(TimeSpan.FromSeconds(1.0));
57: Storyboard.SetTargetName(opacityAnimation, _animatedImage.Name);
58: Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(Image.OpacityProperty));
59:
60: //translate X to Path
61: DoubleAnimationUsingPath translateXAnimation = new DoubleAnimationUsingPath();
62: translateXAnimation.PathGeometry = pathGeometry;
63: translateXAnimation.Duration = TimeSpan.FromSeconds(1.0);
64: translateXAnimation.Source = PathAnimationSource.X;
65: translateXAnimation.AccelerationRatio = 1.0;
66:
67: Storyboard.SetTargetName(translateXAnimation, "AnimatedTranslateTransform");
68: Storyboard.SetTargetProperty(translateXAnimation,
69: new PropertyPath(TranslateTransform.XProperty));
70:
71: //Translate Y to Path
72: DoubleAnimationUsingPath translateYAnimation = new DoubleAnimationUsingPath();
73: translateYAnimation.PathGeometry = pathGeometry;
74: translateYAnimation.Duration = TimeSpan.FromSeconds(1.0);
75: translateYAnimation.Source = PathAnimationSource.Y;
76:
77: Storyboard.SetTargetName(translateYAnimation, "AnimatedTranslateTransform");
78: Storyboard.SetTargetProperty(translateYAnimation,
79: new PropertyPath(TranslateTransform.YProperty));
80:
81: DoubleAnimation scaleXAnimation = new DoubleAnimation(0.4, new Duration(TimeSpan.FromSeconds(1.1)));
82: Storyboard.SetTargetName(scaleXAnimation, "AnimatedScaleTransform");
83: Storyboard.SetTargetProperty(scaleXAnimation, new PropertyPath(ScaleTransform.ScaleXProperty));
84:
85: DoubleAnimation scaleYAnimation = new DoubleAnimation(0.4, new Duration(TimeSpan.FromSeconds(1.1)));
86: Storyboard.SetTargetName(scaleYAnimation, "AnimatedScaleTransform");
87: Storyboard.SetTargetProperty(scaleYAnimation, new PropertyPath(ScaleTransform.ScaleYProperty));
88:
89: indicatorStoryboard.Children.Clear();
90: indicatorStoryboard.Children.Add(scaleXAnimation);
91: indicatorStoryboard.Children.Add(scaleYAnimation);
92: indicatorStoryboard.Children.Add(translateXAnimation);
93: indicatorStoryboard.Children.Add(translateYAnimation);
94: indicatorStoryboard.Children.Add(opacityAnimation);
95: indicatorStoryboard.FillBehavior = FillBehavior.Stop;
96:
97: TimeSpan s = indicatorStoryboard.Children.Max(z => z.Duration.TimeSpan);
98: EventAggregator.GetEvent<HitTestDelayEvent>().Publish(s);
99:
100: _sbPopupAnimation = indicatorStoryboard.Clone();
101: _sbPopupAnimation.Name = "Indicator";
102: _sbPopupAnimation.Completed += PopupStoryBoardEndCompleted;
103: _sbPopupAnimation.Begin(this);
104:
105: NameScope.SetNameScope(this, currentNameScope);
106: }
The code snippet above details an animation when a user clicks on a button within a screen and creates an image that is animated to a list of indicators somewhere arbitrarily on the screen. As the image is animating, its size is being scaled down. The pathFigure is a calculation that determines the starting point and ending point as well as the trajectory of the image during animation.
Conclusion
As developers, we probably feel more comfortable creating animations in code behind. I know i do. However, I would say probably 85% of the animations I generally create are setup in XAML. One way that makes the decision of where to put animations easier is to ask yourself, is my animation related to design or logic? XAML - design, code behind – business logic. If its design (UIElement updates and manipulations) then the animation should be in XAML. If its logic (animations determined by some runtime property or calculation) then the animation should be in code behind.
A while ago I had a debate with my co-worker on when to put a resource in a User Control (whether it would be in XAML or in code behind) or put that resource in a Resource Dictionary. We had this debate because we initially put all our resources in Resource Dictionaries and as our application became more modular this would become a problem when we only want to update a particular section’s resource. Since all our resources were in the same location (our shell project) if a change was necessary, the shell project would also need to be updated. I debated that it was nice to have all resources centrally located. He claimed there were times a resource should be centrally located (when its accessed by multiple controls in multiple projects) and times when it should be directly tied to a particular control. After a while of discussing back and forth the pros and cons of both, I finally sided with him on the following criteria.
- Resource Dictionary
- If multiple controls in a solution need to access a resource then it should be put in a Resource Dictionary
- User Control Resource
- If a resource is specific to that User Control (for example a specific animation that is only performs within a specific User Control) then it should be put in the User Control’s Resource section.
These rules may be simple, but as an application grows it is very easy to overlook this scope for resources and especially since resources aren’t the easiest to debug, this can easily create chaos in future development.
So are there cases where this scope may not work for an application? (Where I was right?) Sure! When discussing this topic with one of our designers, he said it would be much easier for him to update all resources if they were in a centralized location. Designers using Expression Blend do not really want to go through an entire application to find assets they need to update. As we move further towards the direction of designer/developer collaboration, we must change our development techniques somewhat to coincide with a designer’s techniques.
In conclusion, As a developer, I have become fan of specifically defining resources as there is no reason for all controls to have access to them, however I do understand there may be a need to have a centralized location for resource. Being consistent is the most important thing. Whether you divide resources into sections or keep them all in the same Resource Dictionaries, you must stay consistent with the scope you define.
For the last year and a half I have been working extensively on WPF applications. During this time I have learned a great deal in architecting, coding and improving WPF application design and development. This will be my first of a series of blog posts detailing my knowledge gained. One may ask why it has taken so long to begin blogging about this topic? I can answer with one word, laziness. Yes, I have been lazy when it comes to blogging about the things I have learned, however, it is better late then never I presume. So this post is to detail my future blog intentions. Some of the topics I will cover are Resources and Animations, the Modelview-ViewModel pattern, PRISM, Attached Properties, and VisualsHelpers.
To start things off though, below are some links to WPF blogs I read religiously. I have learned a lot from these blogs and feel they are a fabulous starting point for anyone really trying to get deep into WPF development.
Karl Shifflett: Karl on WPF
I have probably learned more from Karl’s blog posts than any other. If you start anywhere, start with Karl’s posts.
Josh Smith: Josh Smith on WPF
Josh is also a must for blog reading. As my co-worker would say, he was doing Command binding before you were born.
WPF Disciples
A collection of blogs from some of the most hard-core WPF developers out there. Very cool stuff.
Bea Stollnitz
Though she blogs about Silverlight now, she has some of the best posts on data binding out there.
As for books, we call Windows Presentation Foundation Unleashed the Bible here at work. I can’t say enough about how great this book is, not just for beginners in WPF, but for people who have been developing in WPF for a while as well.
I recently implemented a recursive function in my code and wanted to write about my experience. First, let me say this is not the first time I've written a recursive function and hopefully won't be the last. However, as a developer I jump at the opportunity to write one. As someone who loves to avoid the conventional for each within another for each statement the idea of a recursive function just gets me all excited inside.
Definition:
- A function that calls itself repeatedly, satisfying some condition is called a Recursive Function.
Why would a developer use recursion?
A better question to ask would be why a developer would not use recursion? The classic for loop within a for loop to update the same property for each item in a multi-dimensioned list is just not practical. The code itself is just not clean.
Example of recursion:
I had a scenario where I needed to gather a list of parameters for rows linked via a parent-child relationship. In a nutshell I had a case where a parent row could be linked to several children rows, which also could be linked to several of their own children rows. This could go on and on. I also had to identify the selected row in my list as well for future analysis. Below is a simple code example of recursion.
private void UpdateGridRowInformation(UltraGridRow row, List<GridRowInformation> list)
{
bool isActiveRow = ((Summary)row.ListObject).Key == _activeRowKey;
int parentListIndex = -1;
if (row.HasParent())
parentListIndex = row.ParentRow.ListIndex;
if (row.HasChild(true))
{
//if item has a child then store its Row Information and call recursion //on Child
UpdateGridRowInformation(row.ChildBands[j].Rows
, list);
UpdateGridRowInformationList(parentListIndex, row.ListIndex, row.Band.Key, row.Expanded, isActiveRow, list);
}
else if (isActiveRow)
UpdateGridRowInformationList(parentListIndex, row.ListIndex, row.Band.Key, row.Expanded, true, list);
}
private void UpdateGridRowInformationList(int parentRowIndex, int listIndex, string bandKey, bool expanded, bool active, List<GridRowInformation> list)
{
GridRowInformation gridRowInformation = new GridRowInformation();
gridRowInformation.ParentRowIndex = parentRowIndex;
gridRowInformation.ListIndex = listIndex;
gridRowInformation.BandKey = bandKey;
gridRowInformation.Expanded = expanded;
gridRowInformation.Active = active;
list.Add(gridRowInformation);
}
This code runs through all parent child relationships and adds particular row elements to a list if that row has its own children. This also adds the selected row’s elements.
Conclusion:
Recursion is clean, easy, and extremely beneficial in programming. There are dangers to watch out for though. Just like for loops there must be a way to exit the function cleanly. Keep in mind that because the function calls itself again and again a spiral effect is created. The first time the function is called will not finish until the instance it calls is finished. That instance does not finish until the instance it calls is finished. And this cycle continues. Therefore, if the function continuously calls itself with no calls ever finishing, the application will be stuck running in that part of the code most likely causing the CPU utilization to increase and the application to halt.
In my case, I will eventually get to the last row of the last child, then the function will unwrap and my code will continue. This is a pretty simple example of recursion however it is a very powerful method used for development.
Conclusion Part II:
To conclude from a personal standpoint, I am a happy coder as I have written a recursive function in my application <g>!
The Chicago competition of Microsoft's PhizzPop Design Challenge took place last night at a club called The Underground. As taken from their website, the PhizzPop Design Challenge pits top interactive, Web, and design agencies against one another to push the limits of technology and creativity in a battle royale. Six teams compete in six cities with the winners of each city then competing at the South by Southwest Interactive Conference in Austin, TX. The Chicago competition had Ratchet, Effective UI, Webitects, Clarity Consulting, Tribal DDB, and Magenic as the companies presenting in the design challenge.
The Challenge
Airplanes! To most, riding an airplane is a miserable experience. Most hate long terminal lines, taking off and landing of a plane, and of course sitting for X number of hours staring at a PG movie or trying to sleep in those uncomfortable chairs. Flying, in general, just sucks. What can be done about this? Well, Microsoft proposed an in-flight concept based on new technology that could improve a passengers enjoyment. The technology used to create this concept is Windows Presentation Foundation or WPF. Each company had three representatives spend two and a half days developing an application using WPF that would somehow make a person's experience on a flight more enjoyable. The airline the teams are creating this for? None other then Howard Hughes nemesis Pan Am Airlines. So this is the challenge! Last night I was able to see all six companies entries and here are the results.
The Teams
Ratchet
Ratchet was the first company to present. They actually teamed up with a design company, sorry I can't remember the name. Its always hard to be the first presenter in a competition as judges tend to remember you the least at the end. You really have to stand out. I don't think it helped that it was obvious these developers and designers were Apple 'fan boys' and were not too fond of Microsoft. I took this by how excited one of them was when he won a Zune in one of the raffles.
Regardless of their opinions of Microsoft, they used the tools designated for this contest and created a pretty nice application. The application was easy on the eye, creative, and I believe a really good effort for first time users of these development tools. They had a simple Kiosk touch screen application on the back of an airplane seat. A user was able to watch movies (though we didn't actually see a video), chat with other users, and contact people not on the flight using Twitter. The provided a business case scenario for this, for example if their flight is running late, they can update work. They also provided an in-flight live map of where the plane's current position is. In all, it was a good opening presentation and set the bar for what to expect from the other teams.
Effective UI
Effective UI was the second company. After researching all the teams going into this competition I thought this was the team that had the best chance. Their company website is very cool, very user interactive, and really demonstrates what I believe is the bar for rich user experiences.
Compared to Ratchet's presentation, Effective UI's blew it away. It was a very nice presentation with some interesting additions. After seeing it I believed it would get some consideration for winning this contest. The application itself had all the same amenities as Ratchet's with the ability to view movies, chat, plane location, etc. But besides having some animation, which made the application just more user appealing, they came up with a fantastic idea to have a touch screen at each user's armrest that interacted with their application. Kind of like a mouse for the user. I do want to add that there were some really nice zoom features in their app as well. All in all, very good application that enhanced the user experience immensely.
Webitects
Webitects was the next company. I didn't really know what to expect from this company. After looking at some of their work I thought this was a really good company for this task, but maybe not in the league of Effective UI. And after their presentation, I still had the same opinion. They had a web page where users could update their flight information at that particular time. For example, lets say their flight is being delayed. A user could go to this website and reschedule a connecting flight for a later time. However, though this is a nice idea, its something that is pretty normal in today's user experience in flying. You can get internet access on a plane and do this. After seeing Effective UI's application, I became all excited with new creative features in a user experience, so though this application was really good, it left an element to be desired.
Clarity Consulting
Clarity Consulting was the fourth company and host for all the developers to work at. I have to be honest, my review here is going to to be extremely biased because I work for Clarity Consulting. They are one of the two development companies in this competition out to show that developers can also be good designers.
To say I was impressed by the presentation wouldn't give enough credit to those guys. They started with a video of an IPhone application. They can use this application to book, review the itinerary of their flight, and even view their boarding pass. They were the first team to present a concept not just for the present user experience but for the future too. They then demonstrated their Kiosk, which was extremely user friendly, extremely animated, and contained a lot of content. The one thing, from a user interface perspective, that stood out from the other applications was the look and feel of their buttons. By having different button sizes, they gave a three dimensional look and feel. Plus their user interface flow was really impressive. Moving from screen to screen seemed to be a smooth transition instead of a jump cut (not to steal a movie term). Definitely was wowed!
Tribal DDB
Tribal DDB, the next company, I thought would be the other big name player based on their website. Their website was very user rich experienced and its clear this companies is really strong in the design environment.
I really liked their presentation. It was very clean, had a lot of animation, and there is a lot to be said about colors. They were the first team to really use colors well. From a visual friendly point of view, this was the best so far. That being said the content was similar to all four previous presentations. They had an obscure movie selection, a very nice seating arrangements viewing GUI, and chat capabilities. These guys are really good at what they do and this application definitely proved that.
Magenic
Magenic was the final company to present and the other development company in this contest. I have met and worked with a few of their past and present employees and think very highly of them as developers. So I was really interested to see what their design team could come up with.
Their presentation was really nice. It wasn't wowing. It wasn't animated. It didn't have features that stood out. But still, it was really nice. It was a very clean application that was easy to move around and had similar features to the previous presentation. One thing I did notice was their team's use of colors, pictures and GUI layout was very good. I find it strange that the two development companies were just fabulous with the rich user experience part of the presentation. This was the one area I thought they would be lacking in.
The Judges
Jeremy Alexis an Assistant Professor at IIT's Institute of Design has a tremendous amount of experience in defining next generation products, services, and business models.
Scott Kinkaid, Vice President of Usability Practices is an expert in defining solutions and integrating the knowledge of traditional lab-based research with online user experiences.
Carlos Segura, one of the most innovative, creative, and talented graphic designers of our time. His artistry is known throughout the world and most of the presenters were extremely honored to just meet him, let alone have him judge their contest.
The Winners
Carlos was the last to talk about the presenters. It was interesting that he said one of the most important criteria the judges were looking for was, in a nutshell, innovation. It was fascinating to know what we could do now with this technology, but where was it headed? What new creative ideas can arise from the use of this technology. He followed by saying therefore hands down the winner is Clarity Consulting! Based on that I think the addition of the IPhone and its usability in the entire flight experience was exactly what the judges were looking for. Using this technology to be innovative is what design is all about. All these teams were very technology savvy, artistic, and did a fabulous job on their presentations. But besides all the cool animation, video, and data in Clarity's presentation they stood out because they were innovative. They saw what could become rather then what currently is. On that note, they deserved to win.
Conclusion
I wanted to attend this contest to not only root my co-workers on, but to continue to see what people are doing with this new technology. I even brought my fiance to give her a visual perspective of the possibilities she always hears me talk about but never sees. I am lucky as I can feed off of these guys and their expertise. Not just as developers, but designers and innovators. So Marlon, Erik, and Kevin congrats to you guys. You truly deserve it for a job well done.
Last night I attended a monthly Chicago IxDA Rich Internet Applications meeting. The IxDA website is http://gamma.ixda.org/local.php. This event was hosted by ARC Worldwide, a marketing services agency. You can visit their website at http://www.arcww.com. As a beginner in Rich Internet Application development, my intent was to see how this technology can be utilized in the real world, what are its advantages and disadvantages, and where do people who use this technology every day feel it is headed in the future.
Demonstrations
In general, I find that when a presenter is demoing their projects it is nice at times to be ‘wowed’, but also nice to feel this was definitely a task I could accomplish. I had both these feelings while watching these demonstrations. The first demo, Wilson Sporting Goods website, I was mildly impressed with. It was pretty, user friendly, and had some interesting animations. However, I thought the lag time on certain items of the application hindered the overall experience. This application was built with a mixture of Flash, AJAX, and HTML.
The next few demos really didn’t catch my attention as they seemed like simple applications. There was a Facebook application which the developers played around with our Facebook Developer Toolkit, I talked to them a little bit about that afterwards.
The real ‘wow’ came from the Microsoft rep and his demos of Silverlight, WPF, and an application called Seadragon. You can check this out at http://labs.live.com/Seadragon.aspx. I was amazed in every aspect at this application. Basically, it displays large amounts of data, such as books and magazines, in a readable and viewable format. The zooming capabilities are simple and cool to use. Also the amount of data it displays, whether its text or pictures, is very impressive. Are we seeing the future of literature? Are books and magazines a thing of the past?
Discussions
There was an interesting debate on the usage of a Rich Application and when the amazement just surpasses the need. An example that was brought up often was the comparison of Google Earth to Google Maps. Google Earth is really cool and everyone has at least used it once, but for practical purposes, most people still use Google Maps to look up directions.
Another topic was what is the driving force behind Rich Applications? Web 2.0 was pushed by the developers and designers as they found this easier for wide distribution of an application. Now that Rich application development is more easily made, with tools like Adobe Flex and Microsoft Silverlight and WPF, how can this impact industry standards to where it’s a viable solution? What kind of applications do our users want? Would users still what something that is easy as opposed to something that is visually stimulating yet harder to work with on an everyday basis? There wasn’t a clear answer to this, but one route discussed was marketing research. Marketing research for application development is more important now than ever.
Conclusion
As someone who is really trying to jump on the design bandwagon from a developer background, this meeting really helped me relate this architecture I still deem ‘fun programming’ with core client application development philosophies that I deal with on a regular basis. I believe the future will consist of a mixture of application design philosophies. I think the conventional client who wants something simple and stupid but does the job will always be there. I do also believe more clients will go the route of a rich application as they’d feel this would better their business scenario. However, that being said with the advancement of technology the way it is, something simple and stupid of the future may be something that’s hard and complex now.
I am looking forward in having fun with these tools, developing games, websites, etc. I am also looking forward to writing my first client-based application with them. The future looks bright for rich application development.
Unable to copy file "obj\Debug\xyz.dll" to "bin\Debug\xyz.dll". The process
cannot access the file 'bin\Debug\xyz.dll' because it is being used by
another process.
I have been getting this error on the project I am working on for quite some time now. It is an annoying error as the only solution before was to restart the IDE which in my case was a headache as it would take 10 minutes to reload being such a big project. In doing some research, I discovered that the library that was locking up was doing so because of the way it was being referenced in regards to its project and other project. It seems if you have a library that is referenced by a library in another project and that 2nd project library is referenced in a 3rd project library, then reference the third project library in the 1st project and then debug through the system, i.e. step through some code, stop the program, re-compile, and this problem will occur.
Alternative attempts to solve this issue:
I first tried to resolve this issue by unlocking to dll from whatever process it was attached to. I used Unlocker 1.85. It is a nice tool that displays what processes are currently attached to a library. It enables you to unlock those processes or kill them. You can download this tool at http://ccollomb.free.fr/unlocker/. I have used this tool in the past for similar issues. However, after I unlocked my particular dll in question and re-compile my code, I still got that error.
Re-start the IDE. Obviously this solution is not acceptable, as I stated before.
Final solution:
VS basically locks the file and you cannot use third party resources to unlock it. Therefore, just use VS! In the Properties of a project in your IDE you have Buld Events. Basically, you can write scripts during pre and post builds of a project. I added these two lines in the pre-build event command line, which basically unlocks the dll within Visual Studio.
IF EXIST $(TargetPath).LOCKED (del $(TargetPath).LOCKED) ELSE (IF EXIST $(TargetPath) (move $(TargetPath) $(TargetPath).LOCKED))
Re-compiled and your unable to copy dll error will not occur. I have spent the last day in coding harmony as I have not had to re-start my IDE! <g>
One of the limitations
of the DataGridView Control within WinForms is that you can only select a few
controls to place in the Grid View. In my case I wanted to add a DateTimePicker
Control within a row of the DataGridView.
I searched for example on how to do this. Microsoft has an example of how to host
controls in windows forms DataGridView cells at http://msdn2.microsoft.com/en-us/netframework/7tas5c80.aspx
but I really didn’t like the fact that you had to create a column class
specifically for that control. It seemed
a tremendous amount of excess code to write for a specific task. I found a simpler way to in a sense, fake
this process. I simply created a
DateTimePicker Control on the form. I
initially set the Visible property to false.
Then, upon a cell click on the DataGridView, I place the DateTimePicker
control within that Cell’s limits, i.e. top, left, height, width. The user then selects a date and as the leave
the DateTimePicker control I post that result back to the particular cell. The code below describes this process.
private void frmCategory_Load(object sender, EventArgs
e)
{
this.productCategoryTableAdapter.Fill(this.dsAdventerWorks.ProductCategory);
// Add the event handlers.
dgCategory.CellClick +=new DataGridViewCellEventHandler(dgCategory_CellClick);
}
protected void dgCategory_CellClick(object sender, DataGridViewCellEventArgs
e)
{
//set Date Picker to false when initially click on cell
if
(dtPicker.Visible)
dtPicker.Visible = false;
if
(e.ColumnIndex == 2)
{
//set
date picker for category datagrid
dtPicker.Size =
dgCategory.CurrentCell.Size;
dtPicker.Top =
dgCategory.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true).Top;
dtPicker.Left =
dgCategory.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true).Left;
if
(!(object.Equals(Convert.ToString(dgCategory.CurrentCell.Value),
"")))
dtPicker.Value = Convert.ToDateTime(dgCategory.CurrentCell.Value);
dtPicker.Visible = true;
}
}
private void dtPicker_ValueChanged(object sender, EventArgs
e)
{
dgCategory.CurrentCell.Value = dtPicker.Value;
dtPicker.Visible = false;
}
To
add, I used this same methodology for a master-detail relationship between two
DataGridViews. I figured that if this
can be done for any control, why not build this relation. The only two differences are I added a
handler for Leaving the second DataGridView and I put the second DataGridView
along with a bound Navigator within a GroupBox control. I did this because I wanted particular
add/delete/update functionality within the second DataGridView.