Home > Blogs
I’ve been doing a lot of XAML work lately on a WPF project, and the client is really concerned about sloppy / ugly XAML. The one problem I found was that Visual Studio 2010 is not really all that great at formatting XAML and it certainly does not format it the way I want it formatted. So I decided to write something that would do the formatting for me, I started with a PowerShell script that I used via PowerConsole. Worked great, but with some free time I decided why not write a proper VS2010 extension.
The key principle behind the formatter is that it only concerns itself with indentation, not what should be on any given line. Visual Studio does offer some options in this regard but the closest thing I could get to what I wanted meant that when I formatted, a typical style Setter was 2 or 3 lines. Multiplying the size of a style by 2 or 3 times makes for a rather large XAML file, not ideal. So you worry about what goes on what line, and I’ll take care of making it all nicely aligned.
Comment indentation is not perfect yet, but it usable, maybe v1.1 will have some improvements.
I’m looking into V2 which will simply intercept the Format Code command. I didn’t go this way in V1 because of the complexity around formatting a selection. Currently I format the entire document. When I finish V2 I’ll post both code samples.
NOTE: I originally wrote this extension back in early October 2010, so there might be a similar tool available now.
BEFORE:

AFTER:

Feedback: I’d love to hear some feedback, if you have something that does not format correctly and feel comfortable sending me the XAML snippet, please do. Any questions, comments, or concerns can be sent to XamlFormatter@danno.ca
Download: You can download the latest version of the XamlFormatter from the Visual Studio Gallery
The dreaded “The remote server returned an error: NotFound” error message in RIA Services can be frustrating if you are not aware of what it really means, and more importantly how to diagnose it.
This generic error message is due to network stack limitation in your browser, basically the browser is intercepting the error and not giving it all to Silverlight. That does not mean there isn’t good information to be found. Your friend here is Fiddler and/or WCF Service Tracing.
NotFound vs OnError: A NotFound generally means that something in the WCF side blew up, OnError will handle errors in your model (or custom code in your DomainService). So when you see NotFound, overriding OnError will not be much help, break points placed inside of it will most likely not be reached during debugging, but its an easy place to start.
The first tool we are going to us is Fiddler, a web debugging proxy with a WCF Binary Inspector. This will show you all the requests are being made and will show you what error code, and possibly what error is being returned by your service. (Using Fiddler with ASP.Net Development Server / Casini)
If there is no good information in Fiddler then the next step is to hit your service url, which you can find in Fiddler. In the picture above you can see that my service is at /ClientBin/HockeyStatsService-Web-HockeyStatsDomainService.svc (ProjectName-Web-DomainServiceName.svc). Remember that RIA Services does not actually generate a .svc file for you, it is handled dynamically by the DomainServiceHttpModule, so don’t go looking for a physical file.
Actual 404: If you hit your service in the browser and you still get a 404, then something is wrong with your deployment.
Check out Saurabh Pant’s Blog or Tim Heuer for good articles on deploying WCF Ria Services to IIS.
If you are using Casini (ASP.NET development server) then make sure your web.config is correct (Has proper references to DomainServiceHttpModule), and that you have a reference in your ASP.NET project to your service library (if you are using RIA Class Libraries, otherwise you should be fine on this point).
Now if you can hit your service url without a 404, but still get a NotFound, and the Fiddler response tab didn’t give you anymore insight we will move on to some other steps.
SvcTraceViewer: Visual Studio has a tool to help you configure WCF, it can be found under TOOLS | WCF Service Configuration Editor. Use this tool to open your Web.Config and then on the ‘Diagnostics’ folder, turn on Message Logging and Tracing. On the ‘Message Logging’ node, LogMessagesAtServiceLevel=true and LogMessagesAtTransportLevel=false.
You can view the generated svclog files with C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe
In my example DomainService I am loading a large amount of hockey stats data. When I open my svclog file and find the error generated I can see that the actual exception being thrown by my service says:
'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '.
Your message obviously might be different, but with that information you should be able to find a solution or at least provide the right information to the WCF RIA Services Forums so they can help find a solution
Another good debugging tip is to turn off custom errors in your Web.Config. <customErrors mode="Off"/> This will provide more informative exceptions to silverlight, however it also exposes information to the user that you may not intend, so do not leave this set to ‘off’ on a publicly available site.
If your error is the same as mine, take a look at Fixing the MaxItemsInObjectGraph.
The MaxItemsInObjectGraph error message comes up fairly often in the WCF RIA Services forums and I just ran into it on a personal project so I thought I’d write a quick blog on how to fix this error.
The exact error message from WCF Trace is:
'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '.
You need to add the following code to your web.config, and replace the following:
HockeyStatsService-Web-HockeyStatsDomainService with YourRiaProjectName-Web-YourDomainServiceName
HockeyStatsService.Web.HockeyStatsDomainService with YourRiaProjectName.Web.YourDomainServiceName
<services>
<service name="HockeyStatsService.Web.HockeyStatsDomainService"
behaviorConfiguration="HockeyStatsService-Web-HockeyStatsDomainService">
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HockeyStatsService-Web-HockeyStatsDomainService">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="655360"/>
</behavior>
</serviceBehaviors>
</behaviors>
This article is valid for the RC version and above
In previous versions of WCF RIA Services, it was extremely difficult to change the service timeouts for your DomainService, you were pretty much stuck with the defaults. The RC release has made it fairly easy, though not all that discoverable.
The single line of code you need is:
((WebDomainClient<LibraryDomainContext.ILibraryDomainServiceContract>)this.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
There are two options on where to put this line of code. First is anywhere after you construct a DomainContext, in which case change ‘this’ to the name of your context object.
The second choice is to create a partial class for your DomainContext and use the partial method OnCreated, which would look like this:
public partial class LibraryDomainContext
{
partial void OnCreated()
{ if(DesignerProperties.GetIsInDesignMode(App.Current.RootVisual))
((WebDomainClient<LibraryDomainContext.ILibraryDomainServiceContract>)this.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
}
}
If you are not sure of the interface you should be using on WebDomainClient, take a look at the constructor of your DomainContext, it is calling the base constructor with the proper WebDomainClient that you should be using above.
EDIT: March 31st 2010
I added a Designer check to the code, this will stop exceptions from being thrown during design time. If you found this post for some other reason than WCF RIA Services RC (or higher) be aware that the above designer check has issues with older versions of Visual Studio. Read this post from Delay's Blog for info
I learned a very important lesson about binding in Silverlight that I thought I would share.
Here is what I was trying to do:
<TextBlock Text=”{Binding Path=MyPeople, Converter={StaticResource OldestPersonNameConverter}}” />
MyPeople is a collection of People and the converter is going to take that collection, find the oldest person and return their name. I thought this would just work and it does the first time. However in this case, adding a new person to MyPeople will NOT trigger the binding to update, your converter will never run again.
Right? Wrong? I’ve been debating the point with a few people at Objectsharp, and I didn’t expect this to fail (some did). I was under the assumption that binding was binding, the magic behind the covers would look for INotifyPropertyChanged or INotifyCollectionChanged regardless of the property you are trying to bind.
This doesn’t work for my example, but in my actual code I was able to bind to myCollection.Count which will fire a PropertyChanged event when you add or remove an item from the collection. In the actual example above, I don’t have a good answer, they all have drawbacks.
This is a quick tip for anyone using WCF RIA Services with Entity Framework. The WCF RIA Services team has fixed what I consider a fairly annoying ‘bug’ with Entity Framework. In Entity Framework the EntityCollection class does not implement INotifyCollectionChanged, however the client side EntityCollection class that RIA uses is part of the RIA framework and they have fixed this issue. They have explicitly implemented the interface however so you will need to cast the EntityCollection to a INotifyCollectionChanged before you see the CollectionChanged event.
If you are using the XMLMetaDataProvider and have a dynamic assembly reference your service might fail with the following error:
The invoked member is not supported in a dynamic assembly
There are two fixes for this problem, one is to use the full attribute names. So ‘DisplayAttribute’ instead of just ‘Display’. Second option is to fix the code in MetadataSet.cs. The problem is with the TryGetType method around line 421. You should be able to find the code below, the GetExportedTypes needs to be changed to GetTypes.
1: // TODO : the metadata file might need a way to specify the set
2: // of source assemblies to load from - for now search all loaded assemblies
3: foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
4: {
5: foreach (Type t in assembly.GetTypes())
6: {
7: if (t.Name == typeName || t.FullName == typeName)
8: {
9: typeMap[typeName] = t;
10: return t;
11: }
12: }
13: }
Thanks to Manfred Lange for the tip on the error message.
The current RIA Services project I’m working on has been using the XMLMetaDataProvider due to the fact that our model and DomainService are in different projects. This rules out defining your metadata in a partial class for each entity. As the project got bigger we noticed that randomly our metadata was not being created at build time. Turns out there is a race condition with loading the XML file and the requests for metadata. Here is the new XmlMetadataProvider.cs file where we now load the dataset in the constructor, not the first time it is requested. After all that, I think we’ll try using Nikhil Kothari’s fluent API style, I like the look of it over the mass amount of XML.
1: internal class XmlMetadataProvider : TypeDescriptionProvider
2: {
3: private Type domainServiceType;
4: private MetadataSet metadataSet;
5:
6: /// <summary>
7: /// Constructor that accepts a metadata context to use when generating custom type descriptors
8: /// </summary>
9: /// <param name="existingProvider">The parent TDP instance</param>
10: /// <param name="domainServiceType">The DomainService Type exposing the entity Types this provider will be registered for</param>
11: public XmlMetadataProvider(TypeDescriptionProvider existingProvider, Type domainServiceType)
12: : base(existingProvider)
13: {
14: this.domainServiceType = domainServiceType;
15: LoadMetadataSet();
16: }
17:
18: public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
19: {
20: return new XmlMetadataTypeDescriptor(this.MetadataSet, objectType, base.GetTypeDescriptor(objectType, instance));
21: }
22:
23: private MetadataSet MetadataSet
24: {
25: get
26: {
27: if (metadataSet == null)
28: {
29: LoadMetadataSet();
30: }
31: return metadataSet;
32: }
33: }
34:
35: private void LoadMetadataSet()
36: {
37: metadataSet = new MetadataSet();
38:
39: // load all the metadata files found
40: IEnumerable<string> metadataFiles = domainServiceType.Assembly.GetManifestResourceNames().Where(p => p.EndsWith(".metadata.xml", StringComparison.OrdinalIgnoreCase));
41: foreach (string metadataFile in metadataFiles)
42: {
43: Stream stream = domainServiceType.Assembly.GetManifestResourceStream(metadataFile);
44: StreamReader streamReader = new StreamReader(stream);
45: String metadata = streamReader.ReadToEnd();
46:
47: try
48: {
49: metadataSet.Load(metadata);
50: }
51: catch (Exception e)
52: {
53: string msg = string.Format(CultureInfo.CurrentCulture, Resource.MetadataLoadError, metadataFile) + " : " + e.Message;
54: throw new InvalidOperationException(msg, e);
55: }
56:
57: }
58: }
59: }
60: }
I just finished upgrading Vista to win7 RC1 on my work laptop. Everything went smoothly right up until I got to work this morning and tried to use VMWare Workstation, which booted up without issue, but the network wasn’t working.
“The network bridge on device VMnet0 is not running” and “VMNet0: Overlapped I/O operation is in progress which failed to connect” were the messages I was getting. The problem was that thewin7 upgrade failed to add the VMWare Bridge Protocol back to my network card. You could probably add this manually, but I just did a repair from my original msi and a reboot later I was up and running.
The first and foremost thing that you missed if you didn’t attend Mix09 was the opportunity to hang out with Barry, Bruce and myself. If you were at Mix09 and didn’t come over and say hello, I can only assume it had something to do with the unnatural resemblance Barry shares with Dr. Evil.
For me, the two big things at Mix were Expression Blend improvements (preview) and Silverlight 3 beta. If you are interested in something other than those two products check out both keynotes and all of the session videos on the Mix09 site. For a nice non-technical change of pace I strongly recommend watching the Day 2 keynote around minute 32 for a great example of UX design. Deborah Adler explains how she set out to change the design of prescription bottles after her grandmother mistakenly took her husbands medication instead of her own.
Expression Blend 3 Preview
Expression Blend took some really big steps to become a more mature product for both developers and designers. For a good overview of what’s new in blend check out Douglas Olsen and Christian Schormann in their ‘The Future of Expression Blend’ session.
SketchFlow
Not actually available in the preview. Sketchflow is an amazingly simple way to sketch out some rough UI designs and publish them in a manner that allows you to actually navigate around your app (no code required, but XAML is actually produced) and also provides a mechanism for stakeholders to leave feedback on each of your designs. Hard to do this functionality justice, so be sure to checkout Christian Schormann’s blog, his presentation at Mix09 or the Day 1 keynote presentation (About minute 97), this had a lot of buzz during the week.
A Better IDE
Blend 3 also went a long way to make the integration of developers and designers much smoother. Developers get Code-Behind Support and TFS Functionality (designers should find this helpful as well hopefully). Designers get SketchFlow and the ability to import files from Adobe Photoshop and Illustrator. Blend can parse these files and replicate the gradients, shapes, layers, etc and create Xaml. A demo of the Adobe support can be found in the Keynote Day 1 (again around the 97 minute mark) and the ‘Integrating Microsoft Expression Blend with Adobe Creative Suite‘ session. Designers (and those of us that pretend to be) will also enjoy the new simple Sample Data panel to generate sample data, or read it from an xml file. This gives you a very simple way to see your Xaml in the designer exactly how you would see in the actual application. There is a sample in the Keynote Day 1 (minute 97, it was an exciting point of the keynote).
Silverlight 3
There was a beta release of Silverlight 3 made available at Mix this year as well as a new drop of the Silverlight Toolkit. Shawn Burke has a great breakdown of the Toolkit drop and the work they did to make it work with Silverlight 2 and 3. Silverlight 3 has made many changes that will make working in Silverlight a lot less painful, bringing it more in line with WPF. Checkout the ‘What’s New In Microsoft Silverlight 3’ session video for a great overview of all the features. The big features that I found interesting were Out Of Browser Support (video), which Bruce explains isn’t really out out of browser, but is still a great feature for giving your Silverlight app that WPF application feel. You can couple out of browser with the new Offline support (video) and really turn your Silverlight application into an almost fully fledged desktop application that can run across several different operating systems.
Application Navigation Framework is great way to get some built-in navigation between pages, I’m really loving this feature. Tim Heuer shows you how to do some URI routing with the deep-linking that is available with this framework as well. There doesn’t seem to be a lot of info out on the internet about this feature, but you can create a new Silverlight Navigation Project and the stubs it creates will explain everything you need to know.
The other features that will probably be of interest to you include Perspective 3D for easy, yet stunning, 3D transforms, the Blur Effect, Element-to-Element Binding (yay! It’s about time), Merged Resource Dictionaries, and Style Inheritance.
Mix09 showed us that in the next few months as Silverlight 3 and Expression Blend 3 get released, the designer-developer workflow gets easier, and you no longer have any excuses to avoid using Silverlight in your personal or business applications. If you haven’t even looked at Silverlight yet, get cracking. If you want to try SL3 and still deploy SL2 apps, check out this article by Jeff Wilcox.
It caught me off guard that the BindingSource is not really UI thread safe. The situation we had was a model running on a background thread that was updating a dataset. My view contained a grid, that was bound to a BindingSource which was bound to a table in that dataset. The result was cross-threading exceptions being thrown as soon as we opened our view. The thread that updates the dataset is the same thread that fires off the events that tell the BindingSource the underlying data has changed, which in turn tells the UI piece that data has changed, all the while still on that background thread.
My first pass at fixing the issue was to override OnListChanged in the BindingSource and marshal the thread back on to the UI thread. This seemed to solve the problem until we bound to the entire dataset instead of just a table. Internally the BindingSource creates a BindingSource for every list inside the collection of lists. In this case, for every table in the dataset.
Thanks to Reflector and the ability to debug into the source code, I found a way to get around the creation of more BindingSources, and instead created my own ObjectsharpBindingSource internally.
This solution is probably only happy path, but that is the only path my code was following so that’s the only code I looked into.
Comments? Questions? Concerns? Don’t like my code? Better idea? Let me know, feedback is always welcome.
The idea behind UIThreadMarshal can be found at this great article by
public class ObjectsharpBindingSource : BindingSource
{
private delegate void OnListChangedDelegate(ListChangedEventArgs e);
private Dictionary<string, ObjectsharpBindingSource> relatedBindingSources;
public ObjectsharpBindingSource() : base()
{
relatedBindingSources = new Dictionary<string, ObjectsharpBindingSource>();
}
public ObjectsharpBindingSource(object dataSource, string dataMember)
: base(dataSource, dataMember)
{
}
public override CurrencyManager GetRelatedCurrencyManager(string dataMember)
{
CurrencyManager result = null;
if (string.IsNullOrEmpty(dataMember))
{
//If you call the CurrencyManager property you end up in a recursive loop
Type t = this.GetType().BaseType;
result = t.InvokeMember("currencyManager", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, this, null) as CurrencyManager;
}
else if (dataMember.IndexOf(".") != -1)
{
//dot notation is not supported by the BindingSource
result = null;
}
else if (relatedBindingSources.ContainsKey(dataMember))
{
result = relatedBindingSources[dataMember].CurrencyManager;
}
else
{
ObjectsharpBindingSource bindingSource = new ObjectsharpBindingSource(this, dataMember);
this.relatedBindingSources.Add(dataMember, bindingSource);
result = bindingSource.CurrencyManager;
}
return result;
}
protected override void OnListChanged(System.ComponentModel.ListChangedEventArgs e)
{
if (UIThreadMarshal.InvokeRequired)
{
OnListChangedDelegate changeDelegate = new OnListChangedDelegate(base.OnListChanged);
UIThreadMarshal.Invoke(new MethodInvoker( delegate { OnListChanged(e); } ));
}
else
{
base.OnListChanged(e);
}
}
}
The client I’m currently working with needed a charting control that would allow us to create something similar to a Gantt chart. Unfortunately the control suite we were using wasn’t quite up to the task. Fortunately a fellow Objectsharpee (and former Dundas employee) told me that Microsoft was going to be putting the Dundas controls they had purchased into the framework, even better was that it had been released just the week previous. I’ve never used Dundas controls previous to this, so I’m not 100% clear what the feature set differences are, or if there are any. The MS Chart control did everything we needed and it was dead simple to do.
All you need to do is download and install the small installer and have .Net 3.5 SP1 already installed.
Chart Docs
Chart Controls
Chart Forums – Note: Not a lot of information in the forums as of this posting, but the Dundas support forums are filled with great, applicable, information.
Chart Samples
Also,
Alex Gorev has started a blog all about the new data visualization in the .Net Framework.
The October Team Foundation Power Tools drop includes three new features:
- TFS Power Shell Extensions
- TFS Windows Shell Extensions
- Team Members Tool
The only one I care about is the Powershell extensions. Keith Hill has a great post with some examples. I already had a script that made some .NET assembly calls to get me the latest good build off of TFS. I converted that script to use the new snapin, and posted it below. I’m sure some of this is not best practices, feel free to let me know if you have a cleaner implementation.
(Get-TfsServer -Name myTfsServer).GetService(Microsoft.TeamFoundation.Build.Client
.IBuildServer]).QueryBuilds("myProjectName", "myBuildName") | where { $_.BuildDefinition.LastGoodBuildUri -eq $_.Uri } | select DropLocation
Two lines in my profile.ps1:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
Today I learned an important lesson about Sql Server 2005, don’t change your default database unless you absolutely have to. I set mine to DatabaseX and then I promptly dropped DatabaseX. When I tried to log in I got a nice error message
Cannot Open User Default Database, Login Failed
I didn’t setup the VM that I was using, so I didn’t know the SA password. I basically had no way to get back into the server. So if you ever find yourself in this predicament, execute the following from the command line:
C:\> sqlcmd -E -d master
1> ALTER LOGIN [YOUR USER NAME HERE] WITH DEFAULT_DATABASE=master
2> GO
That will reset your default database back to master and you can login again.
The current project I'm on is using Infragistics controls exclusively. Infragistics can do some wonderful things, but damn, sometimes it does it horribly. So here are a couple little hints and tips that might save someone a couple of frustrating moments of despair. Find something in my list that I did wrong? Found something I could have done better / cleaner / quicker? Please let me know.
Binding to a List<>
If you are binding your Grid to a BindingSource that in turn is bound to a Generic List, the key of your band needs to be the name of the class your list contains.
List<Message> myList = new List<Message>();
myBindingSource.DataSource = myList;
myUltraGrid.DataSource = myBindingSource;
Band key in your schema is 'Message'. If your class contains another collection there will be bands for those collections which will add 'plus' signs beside all your rows even if that collection is empty. Create another band in your schema with a key equal to your child collection and then set Hidden = true. (See below about the Hidden property...)
The other note for binding to a generic list is that if it isn't an ObservableCollection or BindingList (or anything that doesn't implement IBindingList or IBindingListVIew) then you are not going to get an update when you add or remove and item from the list. If you know these things are happening you can call myBindingsource.ResetBindings(false) when they happen to update your grid with the new bindings.
Good article on what interfaces have what binding functionality.
Can't Find the .Visible property?
This one baffles me, and I'd love to know why some infragistics controls do not have a .Visible property, instead they have a .Hidden. Watch out for that. Apparently this is some sort of VB throw back blah blah blah.
CreationFilter's To Change GroupBy Headers
CreationFilters are a really cool concept that let you change the layout of a lot of Infragistic controls and add new functionality. I used this to add some status lights to the GroupByRows of my grid.
Create a Creation Filter class that implements IUIElementCreationFilter. My AfterCreateChildElements(UIElement parent) does nothing but here is my BeforeCreateChildElements method. This will create 3 icons and some text in the group by row. I create my own text element but if you want to grab the existing text element:
DependentTextUIElement dependentTextUIElement =
parent.GetDescendant(typeof(DependentTextUIElement)) as DependentTextUIElement;
public bool BeforeCreateChildElements(UIElement parent)
{
bool value = false;
if (parent is GroupByRowDescriptionUIElement)
{
int X = 17;
int Y = parent.Rect.Y + 1;
int Width = 516;
int Height = 17;
UltraGridGroupByRow groupByRow = (UltraGridGroupByRow)parent.GetAncestor(typeof(GroupByRowUIElement)).GetContext(typeof(UltraGridGroupByRow));
DeviceStatusInfo deviceInfo = groupByRow.Tag as DeviceStatusInfo;
if (deviceInfo == null)
{
deviceInfo = new DeviceStatusInfo("", DeviceState.Offline, DeviceOnlineState.NotOnline, "", FoundationHelper.GetImage(typeof(string)));
groupByRow.Tag = deviceInfo;
}
string text = deviceInfo.DeviceName;
if (!string.IsNullOrEmpty(deviceInfo.DeviceCurrentOperationsText))
text += " - " + deviceInfo.DeviceCurrentOperationsText;
TextUIElement textElement;
ImageUIElement firstIndicator;
ImageUIElement secondIndicator;
ImageUIElement deviceIcon;
parent.ChildElements.Clear();
deviceIcon = new ImageUIElement(parent, deviceInfo.DeviceImage);
textElement = new TextUIElement(parent, text);
firstIndicator = new ImageUIElement(parent, deviceInfo.DeviceStatusImage);
secondIndicator = new ImageUIElement(parent, deviceInfo.DeviceOnlineImage);
deviceIcon.Rect = new Rectangle(X, Y - 1, deviceInfo.DeviceImage.Width, deviceInfo.DeviceImage.Height);
firstIndicator.Rect = new Rectangle(deviceIcon.Rect.X + deviceIcon.Rect.Width + 2, Y, deviceInfo.DeviceStatusImage.Width, deviceInfo.DeviceStatusImage.Height);
secondIndicator.Rect = new Rectangle(firstIndicator.Rect.X + firstIndicator.Rect.Width + 2, Y, deviceInfo.DeviceOnlineImage.Width, deviceInfo.DeviceOnlineImage.Height);
textElement.Rect = new Rectangle(secondIndicator.Rect.X + secondIndicator.Rect.Width + 2, Y, Width, Height);
parent.ChildElements.Add(deviceIcon);
parent.ChildElements.Add(textElement);
parent.ChildElements.Add(firstIndicator);
if (deviceInfo.DeviceStatus == DeviceState.Online)
{
parent.ChildElements.Add(secondIndicator);
}
firstIndicator.ToolTipItem = deviceInfo.GetDeviceStatusToolTip();
secondIndicator.ToolTipItem = deviceInfo.GetDeviceOnlineStatusToolTip();
value = true;
}
return value;
}
Set the creation filter:
this.ultraGrid.CreationFilter = new GroupRowIndicatorsCreationFilter();
TabClosing Event Order
This tip is kind of specific, but thought I'd post it here anyway. If you are using the Mdi Tabbed Workspace (and I assume the Mdi Tab Control) then a little gotcha is that when the user closes a form, either by clicking the 'X' or by you firing the form.Close() method the Mdi_Tab_Closing method is fired BEFORE the Form_Closing event. If you think about it, it makes sense, however it is a pain in the butt if you want to handle someone closing a tab, and someone closing the whole app differently. In our app we have functionality similar to visual studio, if you caused it to fire?!? Short answer is you can't. So here is a little method that will fire before either Mdi_Tab_Closing and Form_Closing.
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE)
{
applicationClosing = true;
}
base.DefWndProc(ref m);
}
The applicationClosing bool allows me to check if the user hit the X button when I'm in my Mdi_Tab_Closing. If you have an 'Exit' option from a file menu then in that code you will want to set applicationClosing = true in there as well.
I just did a fresh install of Vista Ultimate on my home desktop PC. The install all went fairly smooth except for 2 things:
1) IIS was not installed, and I missed the little checkbox to install ASP support.
2) I had a lot of problems accessing my existing Documents And Settings folders and could not access (only read access) my other partitions. Even as Administrator I could not seem to set permissions on these folders and drives so I could write to them. Thankfully Tim Sneath came to the rescue with a posting about 'Deleting the Undeletable' in which he explains how to reset the permissions on files to give yourself access to them.
it's not unusual to find some folders that can't be accessed, even by an administrator, because their ACLs were set for accounts with SIDs that applied to an old partition
Tim provides a quick batch command that will allow you to reset the proper permissions for the Administrators group.
takeown /f %1 /r /d y
icacls %1 /grant administrators:F /t
Just pass it a directory to start at (it is recursive).
Big thanks to Tim.
When I did a fresh install of Vista on my home desktop machine it did not install IIS by default which is to be expected. But the real problems started when I could not find out how to install ASP support. Anytime I would try and load an aspx file it would say it didn't know how to handle .aspx as a static file. Very frustrating.
Barry Gervin provided a link that shows the step by step instructions on how to properly install IIS 7 on vista, including the slightly hidden ASP.NET support. Is anyone really installing IIS7 and not installing ASP.NET support?
While I was out at the Vista Ice House in Toronto last week they were demo'ing 'DreamScene', which is movies as desktop wallpapers. The basic idea is that you take a small subtle looping video and apply it as your background. Obviously this is eye candy only, but it is pretty impressive eye candy when done properly. There is a video here that shows a couple of examples.
DreamScene is one of those annoying Ultimate Extras which must really drive anyone without Ultimate absolutely nuts. Thankfully I have Ultimate, and managed to get my hands on a beta (the official release is apparently some vague time in the future), only problem is that the beta does not seem to support dual-monitors, something that hopefully will be addressed in time for the final release. WinCustomize has started a page where you can get some DreamScene movies, apparently both in-house created, and user submitted. It doesn't appear that the page is ready for primetime, but you can check it out none the less.
How smart are you?
http://crux.baker.edu/cdavis09/roses.html
A very challenging little game, some people can do it in 5 minutes, apparently others take a year... took me about 20 minutes.
It has been rumoured for months, but finally today it was announced that google had entered the Desktop Search business with
Google Desktop. Anyone that has ever used Microsoft Windows Search knows it is a big pain, and it is slow and the indexing is pretty bad. Needless to say I've been looking forward to the newest addition to the
Google family, and I downloaded it as soon as I heard.
Right off the bat I had a bit of a problem with the install not working because I had Microsoft Firewall Client Version 3 installed, instead of version 4. Even though this is disabled it would not let me continue the install.
Once I was past that problem, it was fine and I started playing with it. It is amazing. Amazing.
It does a one time indexing of your system when there is some idle time, and after that it just keeps track of new and changed files as you work. The searches are amazingly quick and search text files, Word docs, Excel spreadsheets, Outlook mail, browser cache, and all your file names. To do a search for 'jpg' took 0.04seconds and it returned every picture on my computer and every email in which I ever sent, or mentioned a jpg file in. Amazing. Why have you not downloaded it yet?
There is one
beef that I have. I've considered this problem and I've decided it might be a premeditated decision, but I hope it is not. Google Desktop does not look at .cs files, as a C# developer this is very frustrating. For the VB.NET guys it doesn't do .vb files either... Google Desktop will treat .java .c .h .cpp files as text files AND allow for a "filetype:c" or "filetype:java" search. But nothing on .cs files. Google what is the deal with this? I also haven't been able to find anyway to change how certain file types are handled.
Despite this problem I still love it, it integrates itself with
http://www.google.com so that any search on the site will also tell you if you have matches on your own machine, this is done by intercepting google requests and then merging your results with the html when your response comes back. None of your personal info is sent to Google, rest easy. The only thing that is sent is how many searches are run, and how long they took, and even this you can opt out of.
Google is the greatest thing in the world,
Dave will tell you how much
he loves Google if you ask him.
As well as taking over the internet, it is also taking over my machine, I now have my
Gmail, and the
Gmail Notifier,
Picasa for all my pictures,
Google Desktop, and
Google Deskbar. I don't mind this take over a bit.
I recently ran into a problem with the clipboard that is apparently a fairly common problem without a common answer.
The problem occurs while making a temporary copy of the clipboard.
I needed to put something into the clipboard, but I didn't want the user to lose what they already had in there, the easy way that I assumed would work looked like this:
IDataObject oldClipboard = Clipboard.GetDataObject();
//random clipboard manipulation here
Clipboard.SetDataObject(oldClipboard,true);
The true ensures that the data is held in the clipboard even after the program closes. This solution meets with a "The requested clipboard operation failed" message if there is ever anything actually in the clipboard originally.
So here is the proper way of making a copy of the clipboard data, assuming of course that you have no idea what is in the clipboard before you arrived. An important note if you aren't aware of how the clipboard is structured. When you copy text out a richtextbox it is actually stored in several different ways:
Rich Text Format
Rich Text Format Without Objects
RTF As Text
System.String
UnicodeText
Text
The solution:
IDataObject oldClipboard = Clipboard.GetDataObject();
DataObject newClipboard = new DataObject();
string[] s;
s = oldClipboard.GetFormats(); //gets all the possible formats for that data
foreach(string ns in s)
{
newClipboard.SetData(ns,oldClipboard.GetData(ns)); //re-associate the old data with the proper types
}
//this is where your clipboard manipulation goes.
Clipboard.SetDataObject(newClipboard,true); //true makes sure the data persists
Well MSN has knocked one of its shortfalls of the list (it's pretty long).
I heard last week that Microsoft had openned up a web-based version of its popular MSN client, but everytime I tried it the site seemed to be down. However it seems to be up and pretty stable, and it's pretty nice too. Microsoft seems to be doing some pretty great things with WebGUI's, WebOutlook looks almost identical to normal Outlook, and now web MSN looks amazingly like MSN as well.
So everyone give it a try at http://webmessenger.msn.com/
Also a note on SP2, anyone installed it yet? I heard a lot of bad things during the beta stages, I assume that Microsoft fixed all these problems before they turned it Gold, but I'm still a little hesitant. IBM has apparently asked its users to hold off with the install. Apparently this is routine, but I now have a mounting list of 'apparents and hopes'. The list of improvements does sound nice though, maybe not for myself (but the new WiFi improvements should be interesting to see) but more for the family that I have become the unofficial tech-support for. There is a good article at NeoWin about the improvements and beefed up security.
My last note is that at http://sp2torrent.com/index.php you can get a Torrent for the new SP2 (which is a pretty big file). I'm glad to see that there are people trying to show a legal use for P2P before the US Government ups and makes it illegal. My car has illegal uses too, but I haven't heard of any bills before the US Congress to ban cars for any use...
More than a few of my American friends have used Tampa Bay's win in the Stanley Cup finals as an attempt to bash on Canadian hockey. 'Canada hasn't won a cup in more than a decade'.
Haven't they?
Yes geographically the cup has not been won by a team north of the border. But where do you think the cup spends most of its time in the off-season? Canada. Each players gets a day (or week, some amount of time) to bring the cup to their home town. Which means that the cup will spend 2 days south of the border this summer.
Thats right, Tampa Bay has 19 Canadians and only
2 Americans.
Ben Clymer (5 Games, 0 points, 2 shots)
John Grahame (1 Game (only 34 minutes), 3.54 GAA, 0.884 Save %)
And here are some interesting numbers related to the NHL's yearly hardware giveaway. Big thanks to Gord for the numbers.
There have been 112
Stanley Cups:
111 Canadian Captains.
107 Canadian goalies.
39
Conn Smythe Winners, 37 Canadians.
Can you name the non-Canadians? One of the Conn Smythe winners is easy, the other, won back in 1994...
You can email me at daforsyth !at! objectsharp.com if you want the answers.
49
Norris Trophy Winners, 39 Canadians.
Lidstrom 3 times, Chelios 3 times, Leetch twice, Rod Langway twice (actually born in Taiwan).
76
Vezina Winners, 65 Canadians.
Before 1982 this was essentially the
Jennings and I believe that the 100+ Goalies that received the Vezina prior to 1982 are all Canadian. I could be wrong on a couple though.
Also of note is that of the 11 non-Canadians winners, 6 of them are Hasek.
30
Jack Adams, 30 Canadians. This year might be a first, but my vote is with Sutter.
33
Lester B. Pearson Awards (NHLPA voted MVP), 27 Canadians. Jagr
twice, Hasek twice, Naslund, Federov. Hull may be a legal american, but
he was born and bred on Canadian hockey so I don't count him as an
exception.
80 Years of
Hart Trophies. 73 Canadians. Hasek twice, Jagr, Forsberg,
Federov, Mikita twice. Once again I count Hull as a Canadian.
86
Scoring Leaders/Art Ross, 76 Canadians. Jagr 5 times, Mikita 4
times, Forsberg once. For this I'm hazy on the pre-1960 winners, but
I'm fairly certain they were all Canadian.
So there are the numbers, also of note though is that most news outlets are reporting that Calgary had up to 5000 more people at their 'we lost' party than Tampa Bay had for their 'we won' party...
Don't get me wrong, I would have loved Calgary to win the Cup, but by the same token lets not pretend this is an Olympic Gold Medal won by a team of all Americans..... back in 1980.....
Thanks to Dave for the flag.
I'll be the first to admit that I haven't been paying a whole lot of attention to Longhorn. I went to the token meeting, I listen to
Barry and
Dave, but that's about as far as my indoctrination goes. However, maybe today that changes. I started to read a couple articles on the Monad Shell (MSH).
The Monad Shell is Microsoft's kick at the powerful shell engines you find in the *nix systems. As a recent graduate from the academic world which is ruled by the *nix systems, I've always held that a decent shell engine is what Windows lacked the most (I've also added a decent file search engine now).
MSH introduces the new concept of a
Commandlet (Cmdlet), these cmdlet's are the new .exe, .bat, or .com with a twist. The cmdlets are in fact .NET libraries, more closely related to a DLL than an EXE.
With the help of reflection and metadata inside the class, MSH will validate and map command line parameters to the properties of your class/cmdlet. Metadata is also the mechanism that MSH uses to identify a normal class library from a cmdlet.
So far this all sounds somewhat interesting, and maybe useful, but the best is yet to come.
Piping. Microsoft has done something great here, they have taken the already great idea of piping and improved it 100%. Gone are the days of piping text, here are the days of piping objects. Here is one of the examples from the WinHEC presentation. get-process | where “handlecount –gt 400” | sort handlecount | out-chart processname,handlecount I think its pretty self-evident what is happening here except perhaps the last piping command.
out-chart will apparently output the results into an excel chart using the associated values of processname and handlecount. All of these commands now return an output stream that contains and object, not just a flat string representation of what SHOULD have be an object. The cmdlets have access to more than just the single output stream as well, by default they have the output stream, and an error stream. Also available are verbose, debug, and progress streams.
Seamless Navigation. I haven't tried this myself, but it would be nice if it turns out to be true. Microsoft claims that the new shell will enable seamless navigation between the: File system, Registry, AD, and WMI. Lets hope that's the case.
Now, I just need to find a place to install longhorn so I can try all this great stuff out.
The slides from WinHEC can be found
here.
Anyone played with this yet? Let me know what you think/thought.
VS.NET Bug.
I was asked to look into a problem last week involving some moving buttons in the designer.
The problem was occurring in inherited forms where the parent form contained some protected, and
anchored controls. When you resized the child form in the designer and build, Vs.Net would create
some interesting locations and sizes, often time off the form entirely.
These location and size values are set in the
InitializeComponent() which makes
things difficult.
So, after some searching and digging I found an interesting KB article,
that explains its a bug.
However Microsoft's solutions are actually the causes in VS.NET 2003.
Basically there are a few options:
Once you have the controls have been moved, delete the offending locations and sizes from the
InitializeComponent() and they will inherit their values from the parent again.
Create another size and location property and replace the erroneous values with these hard coded values after
InitializeComponent().
Change the protection level to Friend.
Obviously some of these solutions have their own problems, but the bug is fixed in the latest beta
release of Whidbey so just bide your time for a bit.