Wednesday, December 15, 2010

VB + C# Adventures (Final Part)

Now that I’ve been using C# continuously for my current project, I can honestly say that I can switch between VB.NET and C# easily.  As I’ve said before, I learned .NET in C# a long time ago and personal projects are done in C#, but most of my production experience has been using VB.NET

Do I regret having to use VB.NET?  Not at all, because it’s all about the framework, not the syntax.  I like being able to use both languages and achieve the same outcome.  Of course I can’t say that I know C# inside and out, but I can’t say the same about VB.NET either.  I also feel a sense of pride being able to do more than one language and not complain about it.  I still find it funny when my developer friends say something like “Oh I hate VB.NET.” or “I can program in C# about 3x faster than VB.NET.”

So which language do I prefer?  I have always preferred C# over VB.NET, but I’ve never complained and never will, if I have to use VB.NET for a project.  Sometimes there’s no choice in what language you have to use and knowing both is a useful skill to have.  Maybe one day if we need to develop some kind of math intensive library, F# will be thrown my way :)

Friday, December 10, 2010

Closing a WPF Window Through Your ViewModel

I ran into the issue of properly closing a Window (View) from my ViewModel a while ago.  How does one do this without breaking MVVM or adding too much complexity?  Since I’m developing my current project using Prism and my IUnityContainers are injected into my ViewModels, why not just inject this.Close() also?

/**** Window (View) ****/
...
public Window(IUnityContainer unityContainer)
{    
   InitializeComponent();    
   this.DataContext = new ViewModel(unityContainer, this.Close);
}
/**** End Window (View) ****/
 
/**** ViewModel ****/
public class ViewModel
{    
   public ViewModel(IUnityContainer unityContainwer, Action closeAction)    
   {        
      ...        
      CloseCommand = new DelegateCommand(closeAction);    
   }    
   
   public DelegateCommand CloseCommand    
   {        
      get;        
      private set;    
   }
}
/**** End ViewModel ****/

Does this break MVVM at all?  Is testability decreased because I injected the this.Close() method into my ViewModel?  I would argue not since I’ve used the Action delegate.  This seems to be the easiest/simplest way to do what I (and many others) want.  Now there may be some purists out there that don’t want any user entered code in the code-behind, but as you might have guessed, I’m no purist.

Wednesday, December 8, 2010

WPF, MVVM and TextBoxes

Overall, I like WPF and MVVM.  That’s not to say that I think MVVM is a perfect design pattern.  I find myself breaking the purity of MVVM sometimes because I think there’s a lot of compromise needed to do what I want to without adding complexity.

Anyway, one of the biggest gripes about MVVM and TextBoxes is that the data for bound TextBoxes is updated when the TextBox control loses focus.  But that makes sense, right?  Well, what if you’ve updated a TextBox and hit a MenuItem to save your data.  Guess what?  The TextBox doesn’t lose focus and your save takes the stale TextBox data.  Needless to say this is VERY frustrating…

One solution would be to move the focus off of the TextBox like so:

((System.Windows.UIElement)System.Windows.Input.Keyboard.FocusedElement).MoveFocus(new System.Windows.Input.TraversalRequest(System.Windows.Input.FocusNavigationDirection.Next));

You can call that before you actually execute your save command, but even that seems like a bit too much effort to do what should logically be done anyway… I’ve done the above in some of my projects, but there has to be some other way to do what I want…

Instead of using the vanilla Menu control, I turned to Infragistics’ xamMenu.  I was hoping that their menu would take into account something like the issue I was having with my TextBox data.  I was right… sort of.  It turns out that if I use their xamMenu like so:

<ig:xamMenu>
<ig:xamMenuItem Header="Save">
<ig:XamMenuItem.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding SaveCommand}"/>
</ig:XamMenuItem.InputBindings>
</ig:xamMenuItem>
</ig:xamMenu>

The above doesn’t do what I want either… After some experimenting, I found that if I use the vanilla MenuItem elements instead of Infragistics’ XamMenuItem elements, my TextBox data updates and saves.  It seems weird to me that using a combination of the Infragistics xamMenu and the vanilla MenuItem causes the data to update correctly, yet using all Infragistics’ elements doesn’t.

<shrug> In the end I ended up using vanilla Button elements in the xamMenu because using the vanilla MenuItem elements caused spacing issues:

<ig:xamMenu>    
<Button Command="{Binding SaveCommand}" Background="Transparent" BorderBrush="Transparent">
<StackPanel Orientation="Horizontal">
<Image Stretch="None" Source="{StaticResource Image}"/>
<TextBlock Background="Transparent" Margin="4,0,0,0" Text="Save"/>
</StackPanel>
</Button>
</ig:xamMenu>