Articles from .NET

Custom Routed Events in WPF

By Michael Flanakin @ 8:38 AM :: 13606 Views :: .NET :: Digg it!

WPF/Silverlight (XAML) Routed events are one of the foundational components of the WPF and Silverlight architecture. If you're not familiar with the concepts behind routed events, check out Brian NoyesSyndicated feed MSDN Magazine article, Understanding Routed Events and Commands in WPF. This is a great start to understanding the architecture, but Brian doesn't tackle creating your own routed events. After seemingly endless searches, I finally whipped out Reflector to get to the bottom of it. It's pretty simple, but it is different.

For this scenario, I have a collection of items and I needed to raise an event when the selected item changes. Pretty basic. There are three components to this: (1) the routed event identifier, (2) accessor, and (3) event raising call. Again, not too far off what we're used to, but it is slightly different.

public static readonly RoutedEvent SelectedIndexChangedEvent = EventManager.RegisterRoutedEvent("SelectedIndexChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyControl));

/// <summary>
/// Occurs when the selected index changes.
/// </summary>

public event RoutedEventHandler SelectedIndexChanged
{
    add { AddHandler(SelectedIndexChangedEvent, value); }
    remove { RemoveHandler(SelectedIndexChangedEvent, value); }
}

This is where I got stuck. I tried the traditional method to raise the event:

/// <summary>
/// Raises the <see cref="SelectedIndexChanged"/> event.
/// </summary>
/// <param name="args">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>

protected virtual void OnSelectedIndexChanged(RoutedEventArgs args)
{
    if (SelectedIndexChanged != null)
        SelectedIndexChanged(this, args);
}

Obviously, we wouldn't be here if this would have worked. Luckily, all we need to do is replace the if block: RaiseEvent(args). I should also mention that, when you initialize the event arguments, you need to specify the routed event it's being triggered for. this is as simple as new RoutedEventArgs(SelectedIndexChangedEvent).

There can (and probably should) be some deeper thinking with respect to the best way to make this call, but I'm not going to cover that here. I have some half-baked ideas about this as well as what hooking up a routed event should look like, but I'll save that for another time.


WPF and Silverlight (XAML) Tooling

By Michael Flanakin @ 7:51 AM :: 3654 Views :: .NET, Tools/Utilities, User Experience :: Digg it!

WPF/Silverlight XAML

If you haven't played with either WPF or Silverlight, you first need to understand the tooling we have available: Visual Studio, Blend, and Design. Most people don't consider Expression Design, but I'd argue that it's perhaps the best way to get started, depending on what you're doing. This is probably common sense, but if you haven't played with each of the tools, you may not realize how valuable each is to your end goal.

Any developer will most likely want to start with Visual Studio. Try it. You'll find yourself wondering where to start. If you're an old school web developer, like me, you'll stare at the XML code and wonder what to type and finally fall back on the toolbox. If you're a drag-and-drop type (either Win or Web Forms), you'll probably go directly to the toolbox. In either case, you'll most likely find it useful to tweak both the designer and XML... well, that's not completely true. If you're comfortable with XML, you'll eventually stop using the designer because it's just too much of a pain to deal with in Visual Studio. Visual Studio is the best environment [today] if you want to modify markup or code. Don't choose Visual Studio if you're a drag-and-drop type of developer. No matter what type of developer you are, however, you'll find yourself wondering if there's a better way because it just doesn't "feel" right. This is when you'll begin to wonder about that "Blend" thing you heard about.

If you're proficient in Flash development or claim the "designer" moniker, you'll probably start with Expression Blend. Blend is the best tool to build an interface along with some key interaction details (read: animations).  The problem with blend is, there's absolutely no intellisense in XAML, which I find ridiculous. And, just to put salt in the wound, you can't even edit code (C# and VB) files with the tool. This really drives in the fact that the tool is intended for no-code applications. These don't exist. In my experience, Blend will become less and less useful over time. Why? Because you'll start to realize you can't do everything in XAML and will have to move some things to code. This, in conjunction to run-time bindings in XAML will render the Blend design-time experience useless. Visual Studio is the same in this aspect, but it just because apparent that you'll prefer the intellisense, since you'll want to work with the XAML. Unlike Visual Studio, tho, you'll find yourself tweaking the designer more than the XAML. Coding isn't the only thing that will take you out of Blend, tho.

Let's face it, most people start looking at WPF and Silverlight because they want glam. They want beautiful applications with all kinds of frou-frou animations and transitions. This drives me crazy, but I'm not surprised. Choose WPF and/or Silverlight not because it can be pretty, but because it's the next generation user interface technology. This means, if you're building a new Windows application, don't even look at Win Forms. WPF is the way to go. Microsoft hasn't said it, but Win Forms is dead to me. If you have an existing app, I'd recommend you start looking into interop scenarios. Whether you're looking at WPF and/or Silverlight as the next gen platform or not, you're still going to want that glam I mentioned. This is when you should take a look at the often ignored, red-headed step-child of the Expression suite.

Today, Expression Design is a vector graphics editor. Don't expect to switch to Design for raster images (i.e. GIF, JPG, PNG) -- which is what I was hoping to do -- you'll find yourself missing crucial capabilities. I keep Paint.NET on hand for these needs. Design is best used to build creative visual interfaces. I've used it to theorize and bring certain design elements to life. You might do this with windows, buttons, and other framing elements, for instance. I simply find Design to be a better interface for adding glam to my user interface. Note that I'm not referring to animations. Use Blend for animation; use Design for static visual elements, like rotation, embossing, and the like.

To sum it all up, here's what I believe a WPF/Silverlight project should looked like.

  1. Know the difference between graphic and interaction design. Essentially this is the user interface vs. user experience debate, it's important to know the difference for staffing purposes. There is a difference and it's substantial. Don't assume that a graphic designer can architect an ideal interaction or vice-versa.
  2. Get a graphic designer. Unless you have an eye for graphic design, you won't be getting the eye candy you're probably looking for. If you have a passion for this, but it isn't your calling (like me), you might be able to get there eventually, but your time is probably better spent elsewhere.
  3. Get an interaction designer. The fact that we have dialog after dialog and click after click proves how important this one is. I'd argue this is more important than a graphic designer, but I might be biased. The good news is, this can be learned a lot easier than the artistic nature of graphic design. Don't think you can get there without dedication, tho. There are some scientific guidelines, but I have yet to see a good roadmap. It's more about opening your mind and removing yourself and what you might do from the process.
  4. Design is the graphic designer's scratch pad. Whether you start with wire-frames or set your sights on the real deal, Design is great for slapping something together that will eventually be useful. Tweak and tweak and tweak until you get something that looks right. Then, export to XAML.
  5. Blend brings your design to life. Now that you have your XAML, you'll probably need to tweak it to make it slightly more human-readable and maintainable as well as do some initial bindings and animations. This is where three worlds collide. Graphic designers will feel awkward in Blend, but will still be able to be relatively production; interaction designers don't really have a tool, so it will depend on where they came from, but Blend is arguably the best place for them to get started; and, developers are typically more code-focused, so Blend will be awkward for them, too. The bottom line is, Blend isn't the perfect tool for anyone, but it does fill a need. Use it to add interactivity to your design.
  6. Visual Studio gets the job done. When you're ready to make your app do something real, open it in Visual Studio. Arguably the worlds best development environment -- although not without its flaws -- you know why you're here. 'Nuff said.

As a developer who is very comfortable with markup, I've found that this has changed for me over time. I still believe it's a great workflow that supports some moderate back-and-forth -- at least, between Visual Studio and Blend -- but my habits have changed over time. As I've become more and more familiar with XAML, I tend to create visual and interactive effects in Design and Blend, respectively, and then just look at the XAML to figure out how it's done. Occasionally, I'll open my app in Blend, but not too often. This just depends on how big of an effect I'm trying to implement.

The bottom line is, get some experience in all three of these tools. You'll find your own comfort zone. It may include the all-too-bloated and usability-hating Photoshop with a XAML exporter instead of Design or augmenting XAML editing with a light-weight tool like XamlPadX or Kaxaml. No matter what you grow into, know there will be growing pains. WPF and Silverlight have a huge learning curve, but you're buying into the future. The curve is there for a reason, but will hopefully be lessened as the tools improve. I'm also hoping for some major improvements in .NET 4, but I'll try to touch on that later.


VS Team Edition for IT Admins

By Michael Flanakin @ 2:43 PM :: 1444 Views :: .NET, Tools/Utilities, PowerShell :: Digg it!
PowerShell

Yes, I said "admins," but, unfortunately, this isn't an announcement. I'm simply thinking of a version of Visual Studio built for, well, admins. Specifically, I'm envisioning an environment to build and debug PowerShell scripts and cmdlets. Of course, this is only a hop, skip, and a jump away from PowerShell as an official .NET language. Imagine that, PoSh.NET... or, would someone force it to be P#? Either way, I like the idea. As an official language, that also opens it up to compiled scripts, which would be great for those servers without PowerShell installed. Of course, it's just a matter of time before PowerShell is default and the legacy DOS shell is eventually phased out. As a matter of fact, that's the plan for Windows 7 and Server 2008 R2. I'm not sure about Server Core, tho, since there's still the dependency on .NET.


New Logo for .NET

By Michael Flanakin @ 2:32 PM :: 5396 Views :: .NET :: Digg it!

Microsoft .NET

I can't say we needed a new logo for .NET, but there have been a few nice logos coming out of Redmond lately. Actually, I never really considered the .NET logo to be an official logo. It was simply some text with very basic coloring. Either way, we now have a new logo to enjoy. I have to say I like it more, but I don't know if I can say I "love" it. I do like the fact that they're looking to refresh the "look." This makes me wonder if we'll see a new logo for Visual Studio 2010. The Visual Studio logo is something like 10-12 years old. I don't know exactly, but it's perhaps the oldest logo that hasn't changed. Well, other than Windows. The Windows logo changes with every release, but that change is relatively minor. I don't see that logo drastically changing for a long, long time. Actually, Microsoft is probably more likely to release a new OS than change that logo. Who knows... that'd probably still be called "Windows," even tho the change would be reminiscent of the MacOS 9 to 10 change.

Old .NET logo

 New .NET logos


Font Usage in Silverlight

By Michael Flanakin @ 12:54 PM :: 1851 Views :: .NET :: Digg it!

Silverlight

A while ago, when working on my first Silverlight app -- well, "app" might be pushing it -- I wanted to use very specific fonts to achieve a specific look and feel. I didn't put much thought into what was rendered at first, but soon I realized my fonts weren't being used. I ultimately found out that Silverlight is very limited in the built-in fonts you have to choose from. You can only choose from the following:

  • Arial
  • Comic Sans MS
  • Courier New
  • Georgia
  • Lucida Sans Unicode
  • Times New Roman
  • Trebuchet
  • Verdana
  • Wingdings

I was very disappointed when I found out about this because I'm in love with the fonts released with Office 2007, namely Calibri, Cambria, and Consolas. I did say "built-in fonts," however, which is perhaps misleading. The reason for the limited fonts, which I'm sure you can guess, is because Silverlight is aiming to ensure the font you'll need is on the client's machine. What sucks about this is that, even if the client has the font, you still can't use it with a simple name reference, like you can with CSS. There is one work-around, tho.

To use a custom or non-standard font, you simply need to specify a path to the font. The problem with this approach is that it requires the client to download the font file, even if they already have the font locally. I still don't like this, but it's better than no option at all. To specify the font path, you have two options: FontUri property or the <uri>#<font name> syntax within the FontFamily peroperty. This may change in Silverlight 2, but I believe it's consistent with WPF, so I doubt it.

My only hope is that a future version of Silverlight might include a quick check to see if the font is available on the client before downloading it. This should give you the flexibility of using common fonts that aren't considered "standard" to Silverlight without increasing download size significantly across the board.

The last thing I should mention is the use of fall-back fonts. As I understand it, Silverlight support fall-back fonts, but I'm not sure how, unless you're using a custom font. Fall-back fonts in CSS are used when the first font is not available. Since Silverlight limits you to what fonts are theoretically ubiquitous, there doesn't seem to be a need for fall-backs. I can only guess that a fall-back would be used in a case where a font fails to download or the URI is bad.


Bug When Changing Platform (32- vs 64-bit) in Visual Studio

By Michael Flanakin @ 9:43 AM :: 1631 Views :: .NET, Development :: Digg it!

Visual Studio

Someone I work with came to me recently and showed me an interesting bug. In Visual Studio, you can force a project to be built as 32- or 64-bit by going to the project properties Build tab and specifying the target platform. He did this and then proceeded to build the app. This put all the binaries in a \bin\x86 directory. WTF!? I tried it myself and -- not that I doubted him -- I got the same results. The build directory still had the previous value of \bin\Debug, so I found this odd. I changed the build directory to \__bin\Debug and guess what... that's exactly where it went. I thought this was odd, but remembered the IE7 bug on Windows Server 2003 I mentioned a few months back. I changed it back to \bin\Debug and everything worked like a charm.

It looks like changing the target platform changes the build location and, to get around that, change the build directory to something else, save the properties, and change it back. Annoying, but at least you only have to do this once. I went ahead and added this to Connect.


Visual Studio Web Project Fails to Open with COMException

By Michael Flanakin @ 7:46 AM :: 1524 Views :: .NET, Development :: Digg it!

Symptoms

When opening a solution with a web project in Visual Studio, you receive the following error in a popup dialog:

System.Runtime.InteropServices.COMException

Cause

Apparently, this is an issue with IIS configuration. I'm not quite sure why we get such a useless error message, tho. Very annoying. If you're not sure you're seeing this with a web project, load the solution and, when the error pops up, look at the status bar. You should see a "loading" message with the path of the problematic solution.

Resolution

  1. Ignore the errors and let the solution load
  2. In the Solution Explorer, right-click on the project that failed to load, click Edit <project file>
  3. Scroll down to the bottom of the file and look for <UseIIS>True</UseIIS> (located at \Project\ProjectExtensions\VisualStudio\FlavorProperties\WebProjectProperties\UseIIS)
  4. Repace True with False
  5. Save and close the project file
  6. In the Solution Explorer, right-click on the project, click Reload Project

More Information

  • Applies to: Visual Studio 2005, 2008

Resharper Nightly Builds: Game On!

By Michael Flanakin @ 7:09 PM :: 2123 Views :: .NET, Development, Tools/Utilities :: Digg it!

Resharper 4.0

I'm a month and a half late, but the Resharper nightly builds are back! I guess I stopped checking after not seeing any movement for a while. I'm glad to see some activity, tho. This is the most beneficial add-in to Visual Studio I've seen; especially as a productivity geek. What I've been most surprised about is the overall quality of the nightly builds in the past 6 months. Simply outstanding. If you're asking yourself whether to give it a shot or not, I say go for it. You're likely to run into minor issues, but if my experiences are indicative of how well they manage their day-to-day development, this is a team with a very tight ship. I always grab the latest and try to update a few times a week, depending on what I'm in the middle of. If you're not quite as confident as I am, grab a "works here" release. I'm sure you'll see how great this tool is in relatively short time. An absolute must-have for all code-focused developers.


Programmatic User Login (aka Win32 LogonUser)

By Michael Flanakin @ 6:04 AM :: 5955 Views :: .NET, Development :: Digg it!

Programmatic user login

Nothing new here. I just wanted to save this code snippet because it's popped up a few times in the past year and I have to go find it over and over. At least this will make it a little easier for me. This is by no means an authoritative reference -- it's simply what I have used. If you know of something I'm missing, please let me know.

First, you'll need to import the Win32 LogonUser() function:

using System.Runtime.InteropServices;

[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

The only question you probably have is about the logon type and provider parameters. The only provider I know of is the default, 0, which uses "negotiate" (Kerberos, then NTLM) for Windows XP/Server 2003 and later machines. Windows 2000 defaults to NTLM. If you don't know the difference, let me know and I'll explain that in more detail. Here are a list of logon types:

  • Interactive (2) -- Intended for interactive use (duh) with something like terminal server or executing a remote shell. This type caches credentials for disconnected operations.
  • Network (3) -- Intended for high performance servers to authenticate plain-text passwords.
  • Batch (4) -- Intended for batch servers, which act on behalf of the user without his/her direct intervention. Typically used to process many plain-text auth attempts at a time.
  • Service (5) -- Intended for service accounts, which have the "service" privilege enabled -- don't ask me what that is because I don't know.
  • Unlock (7) -- Intended for GINA DLLs (whatever that is) that will interactively use the machine. This type includes some auditing.
  • Clear Text (8) -- Intended for double-hop impersonation scenarios where credentials will be sent to the target server to allow it to also impersonate the user. As I understand it, this is what IIS "Basic" authentication uses. To perform a double-hop, you'll actually have to do a few other things. I won't get into that here, but let me know if that'd be of interest.
  • New Credentials (9) -- Clones current credentials and uses new credentials for outbound connections. Supposedly, this doesn't work with the default provider -- it requires the WINNT50 provider, whatever that is.

The following is a list of the supported providers. I don't know anything about the non-default ones, but figured I'd list them for completeness..

  • Default (0) -- "Negotiate" (Kerberos, then NTLM) for Windows XP/Server 2003 and later; NTLM for Windows
  • NT 3.5 (1)
  • NT 4.0 (2)
  • NT 5.0 (3) -- Required for the "new credentials" logon type.

Next, well... just use it. As you can see, the last parameter in the LogonUser() function is an out parameter for a token which represents the user. This is key. All you need to do is initialize a WindowsIdentity instance with this token and you're well on your way.

using System.Security.Principal;

/// <summary>
/// Creates a new <see cref="WindowsIdentity"/> using the specified credentials.
/// </summary>
/// <remarks>
/// This method assumes an interactive logon for simplicity.
/// </remarks>

public static WindowsIdentity GetIdentity(string domain, string userName, string password)
{
    IntPtr token;
    bool success = LogonUser(userName, domain, password, 2, 0, out token);
    return (success) ? new WindowsIdentity(token) : null;
}

Pretty simple. Of course, we still aren't there, yet. Now that you have the identity, you most likely want to impersonate it. Luckily, this is a simple 2-liner... well, technically two 1-liners. I should also say that, if you want to do impersonation with an already-obtained WindowsIdentity (and you don't have a password), you'll start here.

ImpersonationContext context = GetIdentity("mydomain", "me", "mypassword").Impersonate();
// do work as impersonated user
context.Undo();

That's it. Enjoy!


MSTest Helper: Create Private Accessor

By Michael Flanakin @ 2:03 PM :: 7326 Views :: .NET, Development :: Digg it!

I just found something very useful in Visual Studio 2008 a few days ago. I've been using MSTest for about 2 years, now, and one thing I liked initially was the wizard that would generate test stubs for you. I liked that it gave you somewhere to start. After using it more and more, I began to hate it, tho. I guess the problem is I'm anal about how my code looks and I end up changing everything. So, I started generating the classes myself. The only problem with this approach is the private member accessor the wizard generates is no longer there. Not desirable, but there's an easy fix: run thru the wizard quickly and delete the methods. At least, that was until a few days ago. In VS08, all you need to do is open the file of the desired class, right click the background, select the Create Private Accessor menu item, and then pick the test project to add it to. VS has so many menu items, it's easy to overlook the really useful ones, so I figured this one was worth sharing. Hopefully, Sara Ford Syndicated feed is listening.

Creating a private accessor with MSTest in VS 2008