Showing posts with label XAML. Show all posts
Showing posts with label XAML. Show all posts

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>

Friday, May 8, 2009

WPF Canvas Coordinate System

I noticed that the Canvas class doesn’t use the Cartesian coordinate system for mapping points. For instance, here’s a list of points: 0, 0; 15, 5; 25, 18.  Here’s how these points look when drawn to a Canvas:

wpfCanvasPoints

The above image is fine if that’s what you want to do with the points, but that isn’t the result I wanted.  I had to add a ScaleTransform to the Canvas for it to look the way I wanted.  This can be done in XAML:

<Canvas Name="MainCanvas" Background="AliceBlue" Width="400" Height="200" >
    <Canvas.RenderTransform>
        <ScaleTransform CenterX="200" CenterY="100" ScaleX="1" ScaleY="-1" />
    </Canvas.RenderTransform>
</Canvas>

or programmatically (VB.NET here):

Dim YScale As New ScaleTransform

YScale.ScaleX = 1
YScale.ScaleY = -1
YScale.CenterX = MainCanvas.Width / 2
YScale.CenterY = MainCanvas.Height / 2

MainCanvas.RenderTransform = YScale

You’ll notice the CenterX and CenterY properties are set to the middle of the Canvas.  You can think of this as your pivot point when flipping the Canvas (The CenterX isn’t really needed here since we’re just flipping on the Y axis).The end result is what I was expecting:

wpfCanvasPointsYTransform