I’m doing a little shopping for a virtual dedicated or cloud hosting provider. I need RDP access to install what ever I need, so Azure is out for the time being. The Amazon pricing page and model was giving me a headache, but after taking a break and coming back, I figured out the correct order to click thru the various information screens and have figured it out. Bandwidth, storage and performance needs are also quite small for the time being, but I wouldn’t consider running with anything less then 2GB of ram for Server 2008, and 2 virtual CPUs is nice. Minimum Feature Set: | | Amazon | CrystalTech | GoGrid | MaximumASP | OrcsWeb #1 | OrcsWeb #2 | | Plan Name | 1 Small 24/7 | Hyper-V VPS | Small Biz | MaxV Plan B | B | C | | Total Monthly Price | 97.86 | $279.95 | 202.89 | $178 | $129.99 | $179.99 | | Setup Price | $0 | $199.95 | $0 | $0 | $0 | $0 | | IP Addresses | 1 | 2 | 10 | 2 | 1? | 1? | | VCPU | 1 | ?? | 1 | 2 | 1 | 2 | | RAM | 1.7 | 2 GB | 3 | 2 GB | 2 | 2 | | Disk Quota | 160 GB | 120 GB | 60-120 GB | 40 GB | 60 | 120 | | Backups | Included | $80 + $25 setup | Included | Included | Included | Included | | Bandwidth | 10GB In 10GB Out | 2000 GB | Free Inbound, $0.29/GB Outbound | 200 GB | 250 GB | 250 GB | | Trail | | | | 30 Day Free Trial | | | | Notes | | | For billing, assume 10GB/mo outbound transfer. Disk quota is based on compute unit | | Scott Hanselman uses them | | Cloud Computing Cloud computing is all the rage, but its still in its infancy. As such, features are missing and things are still a little rough around the edges. For true elastic computing, Amazon is the way to go (remember, I was not looking at Azure for this comparison). The reason for this is that you can not stop your instances on GoGrid without deleting them. I’m not even sure if I would consider GoGrid a cloud provider without the ability to stop running instances, they are more like an on-demand virtual dedicated provider. GoGrid does offer some advantages over Amazon. They have free inbound data transfer and hybrid hosting. Hybrid hosting allows you to use their “cloud” offering for your web front end, while you can setup a managed dedicated server with some serious hardware for your backend database. One downside to both services is that you can’t change the specs of an instance after it is created. Since both services let you create your own images (which you have to pay to store), once you get a base machine setup, you can create an image of it and then create new instances from your own image which would cut down on time to deploy. Hopefully the ability to reconfigure an instance is a feature on the roadmaps for both services. If you are going to be doing anything more then single server setups/testing, I would recommend storing your data on the Amazon ESB or GoGrid’s CloudStorage which offers non-instance persisted storage. GoGrid gives you 10GB free, while for the same space, Amazon would charge $1/month. Remember, the ESB or CloudStorage is where you keep your images as well, so it will fill up fast if you storing Windows Server 2008 Images (which clock in around 10GB). While for the most part, ram is ram, the compute definitions differ between Amazon and GoGrid. Amazon offers standard and hi-compute units, while GoGrid just offers more virtual cpu’s with the larger instances (more ram). In my pricing comparison, I was using standard compute size instances from Amazon, which are the equivalent of 1.0-1.2 Ghz Opterons or Xeons. On the GoGrid side, they claim that 1 compute = a P4 2.0 Ghz, so there is a bit of a difference there. If you have a lot of variation in your load, then Amazon will beat out GoGrid just because you don’t have to run around deleting instances, you can just shut them down. If you have a constant known load, then Amazon still beats out GoGrid, as you can take advantage of Amazon Reserved pricing. Reserved pricing requires you to pay a fee up front, but you get lower per hour rates for the duration of the term, 1 or 3 years. However, I like the GoGrid management UI better then the Amazon Control Panel. Amazon: - 2 Small (1.7 GB, 1 compute) Front end web servers
- 1 Small (1.7 GB, 1 compute) App Server
- 1 Large (7.5 GB, 2 VCPU @ 2 compute) Database server
- Load Balancer (Costs extra) + 25 GB of traffic (didn’t increase cost)
- 25 GB inbound
- 100 GB outbound
- Price: $706
Amazon with Reserved - Same as above but using their reserved pricing option for a 1 year term. There is a upfront cost of $1538, but I divided by 12 and added to the other monthly fee for comparison
- Price: 377.67
GoGrid - 2 2GB (1 compute) Front end web servers
- 1 2GB (1 compute) App server
- 1 4GB (3 compute) Database server
- Load Balancer (Free)
- Free Inbound
- 100GB outbound
- Price: $652
Conclusion I’m going to give the Small Instance a try at Amazon, just to see how it works, but will probably end up going with one of the OrcsWeb virtual dedicated servers. For what I currently need, the OrcsWeb provides an economical, and probably more important, simple solution.
This post is part of my PDC09 Conference Notes series. These are my raw notes taken while watching the various session videos from PDC09. Refer to my original post for some conventions I tried to use. PDC Session Link: Networking and Web Services in Silverlight This session went over the different ways to expose data to a Silverlight application. Data access requirements for Silverlight was grouped in two ways and presented as the following graphic: Each example fell somewhere on the X/Y axis of the chart above. Resource Centric was explained to be CRUD operations, while operation centric was more behavior driven. Forms Over Data The first examples were your typical forms over data applications, which are Resource Centric and follow a Request/Reply model. If you control, and have direct access to the data, then RIA services was recommended. Aside from a short demo, not a lot of time was spent on RIA services, as there are other presentations that get into the details. Another option for when you control the data, is to use WCF Data Services, which exposes your data in a RESTFul manner that adheres to the open data protocol (OData). In addition to data you control, services like SharePoint expose the data contained with-in via the open data protocol as well. The advantages to using OData sources over public REST services, is that more is known about the data, so you get a better development experience. If you are working with a public data store exposed with REST, and it’s not OData, then use the enhanced (for Silverlight 4) ClientHttp library. It has a good programming model, and a lot of the deficiencies in previous versions have been solved. For example there is now support for Basic HTTP Authentication secured with SSL. 2 Way and Streaming The second group of examples looked at duplex and streaming scenarios. The first example was a chat application which is an operation centric example that has some request/reply elements, but mainly users a duplex model. WCF was the recommend technology to support the duplex model. The included binary encoder provided a 71% performance improvement over the standard text encoder, even over HTTP. Binary has been the default encoder since Silverlight 3, but is only useful when both endpoints are .Net applications. Duplex itself can be setup in your WCF bindings in one of two ways. For internet scenarios, you will need to use an HTTP binding, which is a polling based duplex model. While not present in the beta that was released at PDC, there are plans to enable HTTP Chunking, which would allow for multiple messages per HTTP request to increase performance. For intranet scenarios, you can use the NetTcp binding for the best performance. Remember, since this is WCF, you code once, and just change your bindings as needed. Silverlight 4 supports UDP multicast, but it is pretty much an intranet only solution, as your network must be configured to support UDP multicast. There is a new Silverlight TCP Socket Policy server project template in the online template gallery (accessible in VS 2010). This makes it very easy to setup the policy server to allow cross domain socket calls for your Silverlight application. An enhancement being considered for Silverlight 4 is that if the application has been elevated, then you will not need to worry about policies.
I have been a big fan of log4net for the past several years. It’s a light weight, reliable, open source logging platform. Today I needed to create FileAppender that created a log file that had the current date in ISO 8601 format. After playing around with various options for the RollingFileAppender, I finally figured out the correct way to accomplish my goal. By adding the type="log4net.Util.PatternString" to the file element in configuration file, you can change the name of the log file at runtime based on properties within log4net. It just so happens, that one of the properties is the current date and time. Here is my appender that I ended up with: <appender name="MyAppender" type="log4net.Appender.FileAppender"> <file type="log4net.Util.PatternString" value="logs\%date{yyyyMMddTHHmmss}.txt" /> <appendToFile value="true"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message%newline"/> </layout> </appender> I had just never seen the type attribute in the file element in any of the samples I’ve worked with before, so it took me awhile to figure out the correct search terms to narrow things down. I also found a site that makes it a lot easier to search the user mailing list: http://old.nabble.com/Log4net---Users-f154.html
Yesterday I gave my first public group presentation to the Madison .Net Users Group on SharePoint 2010. Even though I was working on the demos up until the time I left my house for the meeting, I still managed to do ok. The speaker evaluation ratings were mostly 4 or 5’s, but I would have had to been pretty bad to get anything lower. I did get one comment, and that was that I let my voice trail off, and I remember doing this. I tend to think out loud, so that’s probably what this was. However, for a presentation, talking to one’s self looks kind of goofy, and would be even worse if I was mic’d up. So I need to work on this and make sure that I am either speaking to the group, or not at all. What Worked - Writing out everything I wanted to say, word for word on the notes, which I know that you are not supposed to do (read from notes). This ended up working because I was able to recall most of what I wrote down without looking at the notes. I think that I will continue to try to write out what I want to say as a one more way of practicing for the presentation.
- Overall length of the presentation was good
- Demo to Slide mix was ok for this topic even though it was slide heavy. There was a lot of information to convey, and I felt that the audience was mostly new to SharePoint that they would appreciate a solid foundation
- Demo’s worked out pretty well. I may want to consider adding more code comments to help explain things, as well as help me remember talking points
What Didn’t Work (or what do I need to do next time) - Number one on my list is don’t procrastinate. I need to allow myself enough time to run thru the presentation at least once.
- Create some index cards that contain key information that I want to make sure I cover. This would have been useful on a couple of the slides were there was a lot of information to cover.
- Make sure if you need to read something, that it’s readable in low light situations
- Don’t re-use step by step hands on lab notes with pictures. Demo notes should be on a single page, unless you need to copy code.
Client Object Model There were a couple of questions on the Client Object model, and I wasn’t able to answer them as well as I wanted to. So I did a little research and came up with a key points. The Client Object Model provides a subset of the server object model functionally, which is exposed via a WCF web service. This is intended as a replacement for custom wrappers around the asmx web services that have been available in the past. The client object model is unified across JaveScript, .Net CLR, and the SilverLight CRL, so if you learn it for one platform, you can re-use that knowledge on the other supported platforms. The object model was designed in a way to encourage efficient network utilization thru the use of batching. As a developer, you add a series of commands to the context, invoke the cotnext’s ExecuteQuery method, and receive a set of batch results back from the service in JSON. Most of the details are handled for you by the object model, so it’s not like you have to worry about parsing JSON. Links Here are all of the links I used for my demo. And as an added bonus, I have included links to all of the SharePoint 2010 videos from PDC 2009. I only wish I would have had the time to watch them all before giving my presentation. My Power Point Presentation SharePoint Foundation (Server) 2010 Extra Stuff needed to Install SharePoint 2010 Beta SharePoint 2007 – WSS 3.0 (Some of these resources still apply to 2010) SharePoint PDC Videos
Tomorrow night I am presenting at the Madison .Net Users group. Tonight, I am pulling my hair out, trying to get my demos to work. How far am I? Well I’m on my second demo, but the first one involves 0 programming, so I don’t think that counts. What is was getting in my way, was a nasty System.Data.Services.Client.DataServiceRequestException, complaining of an invalid DateTime value…somewhere. System.Data.Services.Client.DataServiceRequestException was unhandled Message=An error occurred while processing this request. Source=Microsoft.Data.Services.Client StackTrace: at System.Data.Services.Client.DataServiceContext.SaveResult.HandleBatchResponse() at System.Data.Services.Client.DataServiceContext.SaveResult.EndRequest() at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options) at System.Data.Services.Client.DataServiceContext.SaveChanges() at Demo1.Program.AddEmployees() in C:\_Files\Projects\Demo1\Demo1Completed\Demo1Completed\Program.cs:line 48 at Demo1.Program.Main(String[] args) in C:\_Files\Projects\Demo1\Demo1Completed\Demo1Completed\Program.cs:line 19 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: System.Data.Services.Client.DataServiceClientException Message=<?xml version="1.0" encoding="utf-8" standalone="yes"?> <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <code></code> <message xml:lang="en-US">Error reading syndication item: 'Error in line 5 position 14. An error was encountered when parsing a DateTime value in the XML.'.</message> </error> Source=Microsoft.Data.Services.Client StatusCode=400 StackTrace: at System.Data.Services.Client.DataServiceContext.SaveResult.<HandleBatchResponse>d__20.MoveNext() InnerException: After installing Fiddler so I could analyze the post and it’s subsequent response, I tried setting the Modified and Created properties on the Entity to DateTime.Now to give them an actual value. The Modified and Created properties are on all SharePoint list objects. I hadn’t bothered setting them, because they were of type DateTime? and I assumed that SharePoint would set them. As a matter of fact, I watched a PDC session on this very topic and blogged about it. In the demo, the only thing Pablo set was the name and the job title and posted it via CURL, and it worked. I tried setting the values to null, but I got the same error (and why wouldn’t I). I ended up setting the values to DateTime.Min value. This allows the POST operation to succeed, and the Created and Modified values are correctly set by SharePoint. Other notes of interest: - Even though I installed VS 2010 with .Net 4.0, I still had to install the Ado.Net Data services 1.5 CTP2 for SharePoint 2010 to expose data via ListData.svc
- When building an application in VS 2010 with the .Net 4.0, System.Data.Services.Client is added for you when you add a Service Reference. You do not need to add a reference to Microsoft.Data.Services.Client in the CTP 2.
- Be sure to check out the different SaveChangesOptions available when you call SaveChanges for your service. The batch option really speeds things up, but if one update fails, they all fail.
This post is part of my PDC09 Conference Notes series. These are my raw notes taken while watching the various session videos from PDC09. Refer to my original post for some conventions I tried to use. PDC Session Link: Advanced WPF Application Performance Tuning and Analysis This presentation was how you can analyze and tune your WPF applications in 4 key areas: Memory Usage, Cold Startup Time, Warm Startup Time, and Runtime. There were several tools used through out the presentation, and the demos were very well done. I would recommend watching this session to get a better feel for the concepts. The sample application used for the session is called Fishbowl, and is a WPF application that lets you work with Facebook in new ways. Introduction - Measure early and measure often
- Be sure to test on older hardware
- Grab low hanging fruit
- Understand perceived performance (i.e. keep the UI responsive during long running requests)
- Trade Offs
- CPU vs. Memory vs. Disk IO
- Within your application, you may have to pick and choose which features are faster then others
Memory Usage - 150MB of memory was deemed as high for an application like Fishbowl
- I found this to be very surprising given how many seemingly simple WPF apps I have seen using over 200mb of memory at startup. Is memory cheap these days? Yes, unless you count limited memory on Netbooks, older computers, and virtual machines.
- Process Explorer to view overall memory usage
- Sys-internals VMap to view detailed memory usage by process
- Image: .exe, .dll, etc
- Heap: Pure managed applications should have lower native heap then managed heap. You will always have some native heap, as some CLR stuff uses native memory, like the render thread. Images (pictures) are also stored in the native heap and are one source of high native heap usage.
- Managed:
- The cause of the high memory usage was the use of 114 images for the startup animation.
- # of images * width in pixles * hieght in pixles * 4 (32 bit color) = memory usage
- 114 * 272 * 294 * 4 = 34.7MB
- The actual cause turned out to be that the start view was not being disposed after it was finished, so the images remained in memory.
- SaciTech Memory Profiler on memProfiler.com
- Costs money
- WPF perf team uses this tool internally
- Lets you do snapshots so you can compare memory usage over time
- You can drill down by object type, as well as what is holding onto the reference for a particular object.
- Element count (virtualization) is another pain point
Cold Start - Cold start is impacting most by Disk IO
- Windows Performance Tool Kit or Windows SDK?
- xperf command line tool (there is a PDC session on xpef and ETW)
- Event Tracing for windows (ETW): Add ETW statements to your app and profile with xperf
- Demo showed a batch file to start up xperf
- Look for for highest number of reads
- Remove unneeded dll references
- System.Windows.Forms and System.Windows.Drawing shouldn’t be needed in pure WPF application
- If you are using only one or two methods from a dll, you could merge it into your application
- You can use Scitech Mem Profiler to see how many types for dll to see you can eliminate or merge
- If you are using a managed API that is dealing with win32 api’s, you could add p/Inovke’s to your code to eliminate an extra dll.
- Be sure to test in release mode with no debuggers attached
- You can use NGen to speed up cold start, but it might slow down warm start
Warm Start - Warm Start is CPU bound, so you will see high CPU usage. There should also be lower disk IO then cold start.
- If you see low CPU usage, there might be something blocking, like network access (using xperf again)
- CPU Profiler
- WPF Perf
- Part of Windows Performance tool kit
- Check item count, is virtualization enabled. Sometimes virtualization can’t be used, like when list element height is dynamic, which would screw up the scroll bar
Runtime - More WPF Perf usage
- Trouble shoot jerky animations
- Pererator Tool:
- Review hardware IRT’s. In the example, 20 hardware IRTs was too high.
- Problem was traced to drop shadow animation. Solution was to create two elements, one with and one without drop shadow, then toggle visibility
- Other stuff
- Don’t block on the UI thread
- Virtualization when needed
- Freeze your freezables
- No change notification call backs
- Hardware vs. Software
- use RenderCapabilities.Tier to determine when you should dial down visual effects.
This post is part of my PDC09 Conference Notes series. These are my raw notes taken while watching the various session videos from PDC09. Refer to my original post for some conventions I tried to use. PDC Link: Advanced Topics for Building Large-Scale Applications with Microsoft Silverlight Presenter: John Papa (@john_papa) The title of this presentation is a little misleading. It could have just as easily been titled, best practices for building line of business applications in SilverLight. The concepts, if not most of the code can be applied to WPF as well. There was a lot of talk about Prism, which I have not looked at in great detail. However, as a result of this presentation, I will take a closer look at it once I get around to working with SilverLight and WPF more. John pointed out several times that you are able to pick and choose what parts of Prism you want to use, which at least makes it sound a little less invasive then some of the other things to come out of Patterns and Practice. A similar framework which is not developed by Microsoft is Caliburn. Which one is better, is probably open to debate, and both are continued to be developed. John did mention some gaps in Prism, which he developed some code for (posted via his blog), but perhaps these are available in Caliburn. If you are just starting out with SilverLight or WPF, I would suggest looking at both frameworks. If you are already using one or the other, I don’t know how much sense it would make to switch, but I always like to keep my options open. MVVM The first part of the presentation was focused on defining MVVM, or the Model, View, View-Model pattern. The primary benefit of the MVVM pattern, is that is allows for good separation of concerns, which leads to increased testability and maintainability. As you can see below, a lot of time was spent on describing the View-Model and how it fits in, while the View and Model are fairly straight forward. - View: Responsible for rendering the UI only
- Model: Contains your domain entities (i.e. customer, order and order details)
- View-Model:
- Handles the communication between your View and Model thru bindings, commands, events.
- Responsible for providing everything (data) a particular view requires.
- Sometimes your View-Model will look almost identical to your model. Other times, it will contain a mash-up of various entities as required by the view.
- Ensures that your view knows nothing about your model, and that your model doesn’t known anything about the view (or require references to view related dependencies)
Three ways to implement MVVM were presented. I had never considered the first two, while the 3rd one is where frameworks like Prism, Caliburn, Ninject (Inversion of control) come into play. - ViewFirst (Static Resource): View Model can be created as a static resource in the view. This tightly couples the View Model to the view, but gives you the best experience when using Blend (referred to as blenability)
- ViewFirst (Code Behind): The view is injected to the View Model constructor. Since you loose the blendability, I’m not sure why you would pick this over option 3.
- View + View Model Marrige: Use a intermediary to marry the View and the View-Model together. Again, you loose blendability, but this is the approach that everyone takes when using Prism, Caliburn or a home grown framework.
When creating a SilverLight application using MVVM, there are some common functionality that you need to implement, which is where Prism and Caliburn come into play. Since this session used Prism, I will list what was shown, which was limited to what Prism can offer. I expect that Caliburn offers a similar set of functionality. - Shell: Container for all UI modules, such as menus, windows etc.
- Regions: Shell is made up of regions which control where UI modules are displayed.
- Modules: Separate code modules that can be developed in isolation and then loaded by Prism. Modules can talk to one another thru event aggregation (I wonder if MEF would be a better choice)
- Event Aggregation: An eventing model that allows for cross module communication.
Commands: SilverLight 4 adds support for commands, so it is my understanding you do not need to use Prism’s command support anymore. - Bootstrapper: Controls application startup and configuration. Configure your IoC here.
- Delegate Command object for use with commands (very simple class to create if you are not using Prism)
Commands: - Invoke an event on your view and have your view model respond to it.
- When you invoke a command, you expect a response.
- Commands work out of the box well with buttons. However you need to create new command objects that implement ICommand for use with other controls. John puts these objects in his Infrastructure dll, and I think he may have provided some of this code on his blog.
- I still have a lot to learn on commanding
This post is part of my PDC09 Conference Notes series. These are my raw notes taken while watching the various session videos from PDC09. Refer to my original post for some conventions I tried to use. This presentation was part 2 of 2 on SQL Server StreamInsight, and was intended as an advanced look at StreamInsight. If I get around to watching part 1, I will update this post. “Microsoft SQL Server StreamInsight is a powerful platform for developing and deploying complex event processing (CEP) applications. Its high-throughput stream processing architecture and familiar .NET-based development platform enable developers to quickly implement robust and highly efficient event processing applications. Typical event stream sources include data from manufacturing applications, financial trading applications, Web analytics or operational analytics. StreamInsight enables you to develop CEP applications that derive immediate business value from this raw data by lowering the cost to extract, analyze, and correlate the data and by allowing you to monitor, manage, and mine the data for conditions, opportunities, and defects in close to real time.” –Microsoft TechNet StreamInsight was designed to handle input sources that operate in the milisecond range, instead of the second, minute and hour+ range. One of the demo’s shown, demonstrated capturing and processing 60 events per second. StreamInsight will be licensed and released with SQL Server. There was mention of Windows CE and other platform support when they were talking about how the Stream OS provides hardware abstraction for StreamInsight. It seems kind of weird that they didn’t start with Windows CE as the most obvious use (to me) is automation. However, some of the examples shown where at the enterprise server level, which matches up with the definition I pulled from TechNet. StreamInsight makes use of Native memory to avoid garbage collection, and I would assume there are other native code optimizations used for performance reasons. It looks like they are trying to bridge the gap between native code performance and the ease of .net development to support Complex event processing. The following challenges facing complex event processing scenarios necessitated a platform: - Pattern Detection
- Correlate Data
- Aggregate
- Hardware Abstraction
Adapters - “Get” the data into the application
- Built using the adapter framework
- Default adapters wrap the framework in an Observable Patter and expose IEnumerble collections
- Adapters can be Push or Pull
- Adapters can be In-Order or Out-Of Order
- Work with Native Memory
Query Expressions - Allows for data manipulation
- Projection
- Filtering
- Correlation (joins)
- Aggregate over Windows of time (Temporal semantics)
- Time windows can be overlapping or non-overlapping
- Grouping and Aggregation
- Implemented using Linq. Everything except the time aggregation is implemented using out of the box Linq. Linq extensions were created for the time aggregation.
Well it’s not exactly my first, but might as well be. Aside from playing around with WPF a couple of times, I’ve never really sat down and written an application from start to finish. Hopefully, this will be one time where I do finish. Given a set of requirements that contains a series of screens, I am to implement a wizard like interface. Since this application is targeting external customers, looks will count for something. I also want to make sure that there is no confusion between the old application and this new version of the application. To start with, I have installed Expression Studio 3, along with the WPF themes from the WPF toolkit. The themes are part of the WPF futures release in the WPF toolkit project on CodePlex. I then created a new WPF application in Visual Studio (since I was waiting for Expression to download and install) and added the Expression dark theme to my App.Xaml file as a resource dictionary (key section is in bold below). You can see in the source attribute, that I have added themes folder that will contain all of the downloaded themes. I then switched to Expression Blend 3 to begin work on the UI in earnest. <Application x:Class="ThemesSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary Source="Themes\ExpressionDark.xaml"/>
</Application.Resources>
</Application>
As I am a firm believer in not re-inventing a wheel, a quick Bing search gave me some possible WPF wizard implementations. There were a couple of pay options, and one open source option, Piotr Wlodek’s WPF Wizard Control. His sample application and code looked pretty straight forward and I was fairly certain I could massage it into my application without too many problems.
After downloading and extracting the WPF Wizard Control, I was presented with three projects. Pitor’s post uses the code in the WPF Wizard 2 project, so I started there as well. The base control is named Wizard and is in the controls folder. So I created a controls folder in my project as well, and imported Wizard.cs by using the Add Existing Item option in Blend and updated the namespace to match my project.
Next I deleted the MainWindow.xaml file that was created with my new project, and imported the Window1.xaml from the WPF Wizard 2 project. Again, I had to go thru and update the namespace in the code behind file, as well as change the class name in Window1.xaml from WpfWizard to MyNamingConvention.Window1. You will also need to update the reference to Controls on line 4 in Window1.xaml to match your namespace. Once finished, you should be able to build, and see an empty white window in the designer for Window1.
So where is the Wizard? Well, the original project uses a Generic.Xaml file to define the styles of the various UI elements. Since we haven't imported that yet, we don’t see anything. The problem that we need to solve is “merging” the Generic.xaml from the Wpf Wizard project with our themes that we downloaded. I wanted to show you what the application looked like at this point, because I think it shows how WPF operates differently from other types of applications.
In order to have a good starting point, I went ahead and imported the Generic.xaml file from the Wpf Wizard project, and updated the namespace on line 3. After rebuilding, I now start to see some actual UI elements on Window1. You should also note that the check box on the side bar is in fact picking up our ExpressionDark theme. However, the buttons are not picking up the theme, and the background is certainly not appropriate for our ExpressDark theme.
To fix the buttons, I went ahead and removed the style property for each button in Generic.xml, and manually set the margins and width on each button. This allows the buttons to pick up the style from ExpressionDark. There is a way to do some style inheritance, but at this point I don’t think I need it for the buttons. However, you can add the following attribute to the a style tag: BasedOn="{StaticResource {x:Type Button}}” – See this post for more information on the BasedOn attribute.
The background color for the wizard was really giving me problems, so I decided to skip it for now and add the rest of the my wizard pages so I could test that out. Switching back to Window1.xaml (view XAML), you will see that the wizard is made up of a Wizard control tag, and then 1 or more WizardPage child controls (see image below). The hierarchy is:
- Wizard
- WizardPage (CanFinish, CanCancel)
- SideHeader: Option. I’m using it to show progress thru the Wizard
- Border: Main content and additional controls go here
I created my first page, complete with a stack panel in the SideHeader, which contains 6 labels to indicate which step of the Wizard we are on. I then copied and pasted the <WizardPage> 5 times, changed the comment before each page, and updated the label names to get my basic 6 screen wizard. The CanCancel attribute on the Wizard page is set to true by default, so I left that as is, and since I only want someone to be able to finish after getting to the last screen, I set CanFinish to true on the 6th <WizardPage>.
I went back to the background color and finally figured out that you need to change the styles defined in Window1.xaml, not Generic.xaml for:
- x:Key="{x:Static Controls:Wizard.HeaderPanelBorderResourceKey}"
- x:Key="{x:Static Controls:Wizard.SideHeaderPanelBorderResourceKey}"
- x:Key="{x:Static Controls:Wizard.NavigationPanelBorderResourceKey}"
- x:Key="{x:Static Controls:Wizard.ContentPanelBorderResourceKey}"
I’m going to assume that since the styles were defined in two locations, the one in Window1.xaml takes precedence. The styles in Generic.xaml are either there as defaults, or were unintentionally left there by the original author.
My final touch, was to define a second style for my ProgressLabels, called ProgressLabelSelected, which changes the foreground color. When not selected the label is black, when selected the label is white. Here is what Window1.xaml now looks for me after the background and label changes, and I think it’s coming along nicely.
One thing that I do not like about this wizard control, but is present in almost any wizard control I have used, is that it’s difficult to work with the various wizard screens. While you can edit the xaml directly, that is kind of a pain and gives no design time view. Hiding the WizardPage doesn’t work, and so far my only option is to drag the wizard page I want to work with to the top of the list.
I think I’m at a good spot to leave off at for this post as I move onto adding more controls and content to the various Wizard Pages. I’ll come back with a second post on what I learn during that process.
This post is part of my PDC09 Conference Notes series. These are my raw notes taken while watching the various session videos from PDC09. Refer to my original post for some conventions I tried to use. - 4 Scenarios:
- It Works on My Machine
- Choose the right tests
- Solve Complex Debugging Tasks
- Multi-Tier Performance Analysis
- Hard to Reproduce Bugs (It works on my machine/I can't reproduce it)
- Solved by a new feature, IntelliTrace
- Used to be solved by adding Debug statements
- IntelliTrace adds Record, Playback and Rewind
- Demo shows a nightly build that failed
- Click thru the build report to view the IntelliTrace log file
- Shows Threads, test data, system info, loaded modules
- Double click on call stack for the exception (test failure) line where error occurred and takes you to the exact line in the source code.
- Step forwards and backwards in playback to view what was going on (variable state, etc)
- Filter which events you want to see (Asp.Net, ADO.Net, Registy, etc)
- You can now see the return value of methods!
- Records the exact execution path thru branches eliminating guess work.
- No need to add anything to your code
- Various levels of recording. The more you record, the higher the performance impact. No mention was made of how much of a performance hit, although the default settings are not supposed to impact it much.
- Works with Asp.Net as well. Tracks events like gets and posts, allows you to jump into code at that point in time
- How does it Work?
- IntelliTrace record starts, loads CollectionPlan.xml and starts recording
- IntelliTrace does not allow you to change what happens in your code since it's a recording. You can't change a variable for example
- Settings
- IntelliTrace is set in Tools/Options/Intellitrace.
- Maximum amount of disk space for recording
- Where are they stored? C:\ProgramData\Microsoft Visual Studio\10.0\TraceDebugging\
- What do you need to get IntelliTrace on a PC?
- Install visual studio
- Install Test and Lab Manager
- Install Test Agent
IntelliTrace Options Window
- Test Impact Analysis (Choosing the right tests to run)
- Automatically pinpoint which tests are impacted as a result of a code change, including manual tests, although I'm not sure how it works
- TIA, as far as I can tell will only run with tests written in MS Test.
- If it can work with Manual tests, I see some advantage with that, but not running all of your automated tests just seems bad. It seems like they may be fixing a symptom (slow running tests) instead of the problem (poorly written tests)
- Working from the Nightly Build point of view
- You can see impacted tests
- You can drill thru the impacted tests to see what changes caused the tests to be impacted.
- Multi-Tier Performance Analysis
- Scenario: Client Side script in the browser, business logic, database calls
- To start, goto Debug and click Start Profile Analysis
- Select Profile Type
- Select Project, Executable or Asp.net/java script application
- Enable Tier Interaction Profiling
- My Demo (I tried this out locally while watching the video)
- Ran a Asp.Net MVC project
- I run everything as a normal user, not an admin. However, you need to be an admin, but VS prompts your for credentials and it just works.
- You start out in summary view, but there is a drop down at the top (Current View) that gives you access to stuff like Tier Interactions.
- Tier Interactions showed my database calls, the sql executed and how long they took
- It takes a little longer for it to get started, so there is a still a place in my book for using SQL query analyzer while developing, but for end to end debugging of slow pages, this is awesome.
- Report Shows
- Most expensive code paths
- Lets you look at "all code" which will include the base class library and loaded modules
- Jump between various report views by right clicking
- Jump to code
- Collaborative Debugging (Solve Complex Problems)
- While debugging, pin the value of a variable to the editor window (right click while hovering)
- You can add comments to those pinned values
- You can export a break points and data tips as XML which you can then e-mail or what ever
- After you import the break point and data tips, run the app in debug mode
- Application will stop on the break point
- The value and comments will be displayed as exported/imported
- Debug a Crash in a Deployed Application using Dump Files
- When application crashes, open up task manager, find the task, right click and chose create dump file.
- No need to have anything installed to create the dump file
- Open dump file in visual studio, and you can debug it.
- Shows stuff about the computer it was running on
- Modules Loaded
- OS
- Press ctrl+alt+q to get to QuickWatch, and type in $expression, and you'll get info on the exception that caused the crash.
- My Test/Demo
- Create new Widnows forms app with a button. When clicking the button throw new exception.
- Close VS, and run compiled application. Click on the button. The unhandled exception dialog will appear. At this point, go into task manager, find the process, right click and choose create dump file.
- Dump file was created in: C:\Users\USERNAME\AppData\Local\Temp\APPLCIATIONNAME.DMP
- Quit the application and go find the dump file and double click on it, VS will launch.
- You get the basic information, native debugging (machine code), but no managed debugging.
- It looks like you have to download the symbols from Microsoft, and possible set a path for the debug symbols for your application, but I wasn’t able to get it to work when I tried it. I will re-post if I get it to work.
|