Controlling focus from ViewModel objects

2,891 views
Skip to first unread message

Josh Smith

unread,
Mar 14, 2010, 11:54:06 PM3/14/10
to wpf-di...@googlegroups.com
A while back Dr. WPF graced us with his clever hack of controlling input focus from VM objects.  It involved hijacking the VM's IDataErrorInfo implementation, and doing all sorts of evil-genius stuff to make the input caret move to the correct element.  Today while I was trying to read a great novel, I couldn't stop thinking about another way to control input focus from a viewmodel object. 

I put the novel down and did a quick spike of the idea.  The source code is attached (rename it from .DOC to .ZIP since gmail is terrified of ZIP files for some reason).  Here's the general idea...

Implement this interface on your VM class:

/// <summary>
/// Implemented by a ViewModel that needs to control
/// where input focus is in a View.
/// </summary>
public interface IFocusController
{
    /// <summary>
    /// Raised when the input focus should move to 
    /// a control whose 'active' dependency property 
    /// is bound to the specified property.
    /// </summary>
    event EventHandler<MoveFocusEventArgs> MoveFocus;
}

Next, in your VM object (which might implement IDataErrorInfo), do something like this to support a Save button:

public ICommand SaveCommand
{
    get { return new RelayCommand(this.Save); }
}

void Save()
{
    if (this.HasError)
    {
        // The Error property knows which property is invalid.
        this.RaiseMoveFocus(this.Error);
    }
    else
    {
        // Save to database...
        System.Windows.MessageBox.Show("Saved");
    }
}

bool HasError
{
    get { return _validatedProperties.Any(prop => !String.IsNullOrEmpty(this[prop])); }
}

public event EventHandler<MoveFocusEventArgs> MoveFocus;

void RaiseMoveFocus(string focusedProperty)
{
    var handler = this.MoveFocus;
    if (handler != null)
    {
        handler(this, new MoveFocusEventArgs(focusedProperty));
    }
}

Lastly, in your View, use my terribly(?) named attached property to specify which DP on your elements is bound to the validated property of the VM, for example:

<TextBox 
    Text="{Binding Path=FirstName, ValidatesOnDataErrors=True}" 
    local:FocusControl.ValidatedProperty="TextBox.Text"
    />

I'm not sure that I like this approach yet.  It's a pretty important topic, so I thought I'd share this out amongst the Disciples for feedback.

Thanks,
Josh

WpfApplication1.zip.DOC

Sacha Barber

unread,
Mar 15, 2010, 4:55:03 AM3/15/10
to wpf-di...@googlegroups.com
I like it.
--
Sacha Barber
sacha....@gmail.com

Peter O'Hanlon

unread,
Mar 15, 2010, 5:03:37 AM3/15/10
to wpf-di...@googlegroups.com
I like it - I know that it feels "dirty", but it's actually pretty darn cool.

On Mon, Mar 15, 2010 at 3:54 AM, Josh Smith <flappl...@gmail.com> wrote:



--
Peter O'Hanlon

Josh Smith

unread,
Mar 15, 2010, 10:24:25 AM3/15/10
to wpf-di...@googlegroups.com
Thanks.  Any pitfalls or gotchas sticking their heads out?

Peter O'Hanlon

unread,
Mar 15, 2010, 10:31:01 AM3/15/10
to wpf-di...@googlegroups.com
The only thing that stands out to me is that this is going to have to be applied in a lot of places in a typical LOB application, so that might be a little bit tedious. What effects do FocusScope's have here? I'll need to play around with this a bit just to make sure there aren't any edge cases that occur (I'm primarily thinking of cases where loss of focus to a menu/toolbar triggers the validation but the parent FocusScope has changed from the textbox).
 
Pete

--
Peter O'Hanlon

Josh Smith

unread,
Mar 15, 2010, 11:08:26 AM3/15/10
to wpf-di...@googlegroups.com
Thanks Pete. I was thinking that there could be an attached property of type bool that is set on an element, instead of setting ValidatedProperty.  When set, that attached property figures out which property on the element to monitor, such as Text on a TextBox.  This would make it easier than having to specify the property, though that would still be an option if you need to specify it.

I'll have to look into FocusScopes, though I don't see any issues there (I might be overlooking something...).

Josh

Peter O'Hanlon

unread,
Mar 15, 2010, 11:12:55 AM3/15/10
to wpf-di...@googlegroups.com
Sounds good. As far as the FocusScopes go, there shouldn't be any issues, but it's an edge case to consider (I've been bitten too many times by custom FocusScopes).
--
Peter O'Hanlon

Marlon Grech

unread,
Mar 15, 2010, 1:46:11 PM3/15/10
to wpf-di...@googlegroups.com
mmm... interesting approach... what about leveraging Namescopes for such a thing?

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App

Josh Smith

unread,
Mar 15, 2010, 1:50:11 PM3/15/10
to wpf-di...@googlegroups.com
What do you have in mind?

Marlon Grech

unread,
Mar 15, 2010, 2:33:17 PM3/15/10
to wpf-di...@googlegroups.com
something like this... but I need to do something else so that its cooler...

The Idea is that rather then setting an attached property to every element you want to control you just set it once and find that element by using WPF Namescopes.

Attached is a prototype... yet I just built this now... did not test it... and probably I have bugs all over the place.,... I just did it to show you what I mean



Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



TestFocus.zip.doc

Sacha Barber

unread,
Mar 15, 2010, 2:57:42 PM3/15/10
to wpf-di...@googlegroups.com
I like it actually Marlon, very nice, though I have not had that much to do with FocusScope to be honest, I must be doing it all wrong I guess.
--
Sacha Barber
sacha....@gmail.com

Peter O'Hanlon

unread,
Mar 15, 2010, 4:08:26 PM3/15/10
to wpf-di...@googlegroups.com
I like that Marlon. It's a neat twist, and an innovative use of namescopes.

On Mon, Mar 15, 2010 at 6:33 PM, Marlon Grech <marlo...@gmail.com> wrote:



--
Peter O'Hanlon

Marlon Grech

unread,
Mar 15, 2010, 4:22:21 PM3/15/10
to wpf-di...@googlegroups.com
yea I think Namescope can be leveraged in this specific scenario...

there is another way of doing this which would actually be cooler because you do not need to implement any interfaces... let me write a quick sample.... brb


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Daniel Vaughan

unread,
Mar 15, 2010, 4:25:54 PM3/15/10
to WPF Disciples
Good thinking Marlon. As Pete said, very innovative.


On Mar 15, 7:33 pm, Marlon Grech <marlongr...@gmail.com> wrote:
> something like this... but I need to do something else so that its cooler...
>
> The Idea is that rather then setting an attached property to every element
> you want to control you just set it once and find that element by using WPF
> Namescopes.
>
> Attached is a prototype... yet I just built this now... did not test it...
> and probably I have bugs all over the place.,... I just did it to show you
> what I mean
>
> Regards
> Marlon

> WPF Blog -http://marlongrech.wordpress.com/


> Microsoft MVP for Client App
>

> On Mon, Mar 15, 2010 at 5:50 PM, Josh Smith <flappleja...@gmail.com> wrote:
> > What do you have in mind?
>

> > On Mon, Mar 15, 2010 at 10:46 AM, Marlon Grech <marlongr...@gmail.com>wrote:
>
> >> mmm... interesting approach... what about leveraging Namescopes for such a
> >> thing?
>
> >> Regards
> >> Marlon

> >> WPF Blog -http://marlongrech.wordpress.com/


> >> Microsoft MVP for Client App
>

> >> On Mon, Mar 15, 2010 at 3:12 PM, Peter O'Hanlon <pete.ohan...@gmail.com>wrote:
>
> >>> Sounds good. As far as the FocusScopes go, there shouldn't be any issues,
> >>> but it's an edge case to consider (I've been bitten too many times by custom
> >>> FocusScopes).
>

> >>> On Mon, Mar 15, 2010 at 3:08 PM, Josh Smith <flappleja...@gmail.com>wrote:
>
> >>>> Thanks Pete. I was thinking that there could be an attached property of
> >>>> type bool that is set on an element, instead of setting ValidatedProperty.
> >>>>  When set, that attached property figures out which property on the element
> >>>> to monitor, such as Text on a TextBox.  This would make it easier than
> >>>> having to specify the property, though that would still be an option if you
> >>>> need to specify it.
>
> >>>> I'll have to look into FocusScopes, though I don't see any issues there
> >>>> (I might be overlooking something...).
>
> >>>> Josh
>

> >>>> On Mon, Mar 15, 2010 at 6:31 AM, Peter O'Hanlon <pete.ohan...@gmail.com


> >>>> > wrote:
>
> >>>>> The only thing that stands out to me is that this is going to have to
> >>>>> be applied in a lot of places in a typical LOB application, so that might be
> >>>>> a little bit tedious. What effects do FocusScope's have here? I'll need to
> >>>>> play around with this a bit just to make sure there aren't any edge cases
> >>>>> that occur (I'm primarily thinking of cases where loss of focus to a
> >>>>> menu/toolbar triggers the validation but the parent FocusScope has changed
> >>>>> from the textbox).
>
> >>>>> Pete
>

> >>>>>   On Mon, Mar 15, 2010 at 2:24 PM, Josh Smith <flappleja...@gmail.com>wrote:
>
> >>>>>> Thanks.  Any pitfalls or gotchas sticking their heads out?
>
> >>>>>> On Mon, Mar 15, 2010 at 1:03 AM, Peter O'Hanlon <
> >>>>>> pete.ohan...@gmail.com> wrote:
>
> >>>>>>> I like it - I know that it feels "dirty", but it's actually pretty
> >>>>>>> darn cool.
>

> >>>>>>>  On Mon, Mar 15, 2010 at 3:54 AM, Josh Smith <flappleja...@gmail.com


> >>>>>>> > wrote:
>
> >>>>>>>> A while back Dr. WPF graced us with his clever hack of controlling
> >>>>>>>> input focus from VM objects.  It involved hijacking the VM's IDataErrorInfo
> >>>>>>>> implementation, and doing all sorts of evil-genius stuff to make the input

> >>>>>>>> caret move to the correct element.  Today while I was *trying* to

> >>>>>>>>     *local:FocusControl.ValidatedProperty="TextBox.Text"*


> >>>>>>>>     />
>
> >>>>>>>> I'm not sure that I like this approach yet.  It's a pretty important
> >>>>>>>> topic, so I thought I'd share this out amongst the Disciples for feedback.
>
> >>>>>>>> Thanks,
> >>>>>>>> Josh
>
> >>>>>>> --
> >>>>>>> Peter O'Hanlon
>
> >>>>> --
> >>>>> Peter O'Hanlon
>
> >>> --
> >>> Peter O'Hanlon
>
>
>

>  TestFocus.zip.doc
> 140KViewDownload

Marlon Grech

unread,
Mar 15, 2010, 4:42:22 PM3/15/10
to wpf-di...@googlegroups.com
Attached is take 2...

Basically I hate it when my ViewModel has to implement all these interfaces... It feels like back in Java days to me...

so the idea here is to still use namescopes but leverage the databinding capabilities of WPF... so that you can do something like this

<Grid focusStuff:FocusedBehaviourTake2.FocusElement="{Binding Focus}">

and in the VM

Save = new RelayCommand( x => Focus= "Name");

Basically in the ViewModel you set a property that exposes the element that should get focus. The attached behavior (which accepts binding) will get triggered when the property changes. THERE IS ONE SIDE EFFECT OF THIS. Basically if the viewmodel sets the Focus property to be the same the attached behavior will not get triggered again... this might be a show stopper for this idea... what do you guys think?

which approach would you like best?


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/

Microsoft MVP for Client App



TestFocus Take 2.zip.doc

Marlon Grech

unread,
Mar 15, 2010, 4:43:33 PM3/15/10
to wpf-di...@googlegroups.com
P.S sorry for ugly code and all that but the code I produced is just to show you guys the idea ....


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Sacha Barber

unread,
Mar 15, 2010, 5:18:58 PM3/15/10
to wpf-di...@googlegroups.com
I prefer option 1 actually
--
Sacha Barber
sacha....@gmail.com

Peter O'Hanlon

unread,
Mar 15, 2010, 5:20:43 PM3/15/10
to wpf-di...@googlegroups.com
Same here.
--
Peter O'Hanlon

Marlon Grech

unread,
Mar 15, 2010, 5:56:09 PM3/15/10
to wpf-di...@googlegroups.com
may I ask why you guys prefer option 1? Just for curiosity...
Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Sacha Barber

unread,
Mar 15, 2010, 6:04:24 PM3/15/10
to wpf-di...@googlegroups.com
I do not like the idea of the Binding not firing.
--
Sacha Barber
sacha....@gmail.com

Marlon Grech

unread,
Mar 15, 2010, 6:06:10 PM3/15/10
to wpf-di...@googlegroups.com
true ... it is a show stopper isn't it...

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Peter O'Hanlon

unread,
Mar 15, 2010, 6:06:14 PM3/15/10
to wpf-di...@googlegroups.com
It just feels cleaner to me (plus the namescope way is way cool).
--
Peter O'Hanlon

Marlon Grech

unread,
Mar 15, 2010, 6:08:04 PM3/15/10
to wpf-di...@googlegroups.com
actually there is a way how you can work around that... but I am not gonna do that... the other way is to inject a command in the ViewModel and the ViewModel can then execute that command...

actually you know what... I am at a pub and have nothing to do (besides drinking beer) so I will have a go with that Idea :) lol

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Marlon Grech

unread,
Mar 15, 2010, 6:50:31 PM3/15/10
to wpf-di...@googlegroups.com
here is take 3 :)

P.S I am on my second Pint so excuse any stupid mistakes :D

The idea is that the Attached behavior injects a command that the ViewModel can use to get an element focused. (it is still using the namescope idea).

This is what the ViewModel does
ICommand focusCommand;
        public ICommand FocusCommand
        {
            get { return focusCommand; }
            set
            {
                focusCommand = value;
                OnPropertyChanged("FocusCommand");
            }
        }

        public ICommand Save { get; private set; }

        public MyViewModel()
        {
            Save = new RelayCommand(x =>
            {
                if (FocusCommand.CanExecute("Name"))
                    FocusCommand.Execute("Name");
             }

So the ViewModel exposes a command property but never sets it.

Then in the View you work a bit of magic
<Grid focusStuff:FocusedBehaviourTake3.HandleFocusElement="True" focusStuff:FocusedBehaviourTake3.FocusCommand="{Binding FocusCommand, Mode=TwoWay}" >

Basically the Behaviour will inject a command that the ViewModel will execute. This option gives also the oportunity to check if you can actually give focus to the control which is very interesting from the ViewModel stand point. What do you think?

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



TestFocus Take 3.zip.doc

Marlon Grech

unread,
Mar 15, 2010, 7:22:58 PM3/15/10
to wpf-di...@googlegroups.com
to make this less magic one could create an interface and make the Attached Behaviour set a property on that interface.... yet having said that then why not go to Take 1.... mmmm.... aa well... its good to have option now all you need to do is pick one :)

But yea I think the first option is probably ideal.. the other options are there because WPF is awesome and you can do crazy shit.... oww my beer is talking now.. :)


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Josh Smith

unread,
Mar 15, 2010, 10:33:38 PM3/15/10
to wpf-di...@googlegroups.com
I finally got some time to look over your code samples, Marlon.  It's definitely a cool idea, and shows some creative thinking.  

With that said, I wouldn't use it.  I try to avoid naming elements as much as possible, and this technique relies on assigning names to elements.  Not only that, but the name of an element must match the name of the VM property to which it's "important" property is bound.  I can see this leading to refactoring problems, learnability degradation, and general maintainability issues.  It's too magical, you f'ing Wizard you! ;-)

The reason I used the approach shown in my original code spike is threefold.

<TextBox 
    Text="{Binding Path=FirstName, ValidatesOnDataErrors=True}" 
    local:FocusControl.ValidatedProperty="TextBox.Text"
    />

Fold #1 - By specifying the dependency property to which the validated VM property is bound, I avoid unnecessary duplication of VM property names in the View.

Fold #2 - There is no need to walk down the element tree, searching for elements that match a criterion.  This improves performance, especially in obese UIs.

Fold #3 - By making the 'ValidatedProperty' attached DP of type DependencyProperty, I get compile-time name verification.

I'm pondering the idea of creating a Binding subclass that taps into some kind of scoped focus management container upon creation.  You could then use that Binding extension to have the binding automatically register itself with the entity responsible for satisfying focus change requests from VM.

Tally ho!
Josh

Josh Smith

unread,
Mar 15, 2010, 11:38:44 PM3/15/10
to wpf-di...@googlegroups.com
I took a stab at the custom binding approach that I mentioned earlier.  The new code is attached.  Here's all that's required in the XAML to make an element be a target for focus movement.

<TextBox 
    Text="{local:FocusBinding Binding={Binding Path=FirstName, ValidatesOnDataErrors=True}}" 
    />

Technically, the ValidatesOnDataErrors isn't needed.  

Here's how FocusBinding works:

public class FocusBinding : MarkupExtension
{
    public FocusBinding()
    {
    }

    public Binding Binding { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        if (provideValueTarget != null)
        {
            var element = provideValueTarget.TargetObject as DependencyObject;
            var property = provideValueTarget.TargetProperty as DependencyProperty;
            FocusControl.SetFocusableProperty(element, property);
        }
        return this.Binding.ProvideValue(serviceProvider);
    }
}

If BindingBase.ProvideValue wasn't sealed, I could have just overridden that method instead of creating a wrapper markup extension.  Oh well.

Josh
WpfApplication1 TAKE 2.zip.DOC

Josh Smith

unread,
Mar 15, 2010, 11:40:55 PM3/15/10
to wpf-di...@googlegroups.com
On second thought, ProvideValue should check if the Binding property is null, and act like a {Binding} if it is:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    var provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
    if (provideValueTarget != null)
    {
        var element = provideValueTarget.TargetObject as DependencyObject;
        var property = provideValueTarget.TargetProperty as DependencyProperty;
        FocusControl.SetFocusableProperty(element, property);
    }

    if (this.Binding == null)
        this.Binding = new Binding();

    return this.Binding.ProvideValue(serviceProvider);

Sacha Barber

unread,
Mar 16, 2010, 5:05:22 AM3/16/10
to wpf-di...@googlegroups.com
I like this last one from Josh a lot too. Very elegant both Josh / Marlon
--
Sacha Barber
sacha....@gmail.com

Philipp Sumi

unread,
Mar 16, 2010, 5:23:33 AM3/16/10
to wpf-di...@googlegroups.com

Very nice approach, Josh - markup extensions are one of the really underestimated tools in a WPF developer's toolbox. In case you want to save yourself the plumbing of all the binding properties, you can take the source of this decorator class here - I'm using that one quite often for similar scenarios, but encapsulates the whole binding stuff in a base class: http://www.hardcodet.net/2008/04/wpf-custom-binding-class

 

However, maybe one could solve the problem more designer (less XAML) friendly using Blend behaviors? I gonna have to check that out.

Philipp Sumi

unread,
Mar 16, 2010, 7:58:30 AM3/16/10
to wpf-di...@googlegroups.com

Ok, I did a quick dive into Blend behaviors and came up with an alternative (but not necessarily better) approach.

I put the sample here, Google didn't like my attachment despite the changed extension: http://www.hardcodet.net/uploads/focus-behaviors.zip

 

What's nice about the binding is that is creates the relation between the focusing and a bound property. With a behavior, we would have to define the bound dependency property ourselves. Accordingly, I came up with (or rather reused, I'm currently on something related) an abstract behavior class that delegates the resolution of the bound property to the implementations:

 

public abstract class FocusBehaviorBase : Behavior<FrameworkElement>

{

  protected abstract DependencyProperty GetSourceProperty();

 

 

  protected override void OnAttached()

  {

    ...

  }

}

 

 

With this behavior in place, I created two behavior classes - one that can be used specifically for TextBoxes, and a generic one that expects me to declare the bound dependency property within Blend:

 

public class TextBoxFocusBehavior : FocusBehaviorBase

{

  protected override DependencyProperty GetSourceProperty()

  {

    return TextBox.TextProperty;

  }

}

 

 

public class CustomFocusBehavior : FocusBehaviorBase

{

  public static readonly DependencyProperty BoundSourceProperty =

    DependencyProperty.Register("BoundSource", typeof (DependencyProperty), typeof (CustomFocusBehavior));

 

 

  public DependencyProperty BoundSource

  {

    get { return (DependencyProperty)GetValue(BoundSourceProperty); }

    set { SetValue(BoundSourceProperty, value); }

  }

 

  protected override DependencyProperty GetSourceProperty()

  {

    return BoundSource;

  }

}

 

 

 

My current implementation does not leverage any further possibilities I have with behaviors, but sticks close to Josh's implementation, using the FocusControl helper class. Here's my minimal implementation within the behavior base class (without cleanup etc):

 

public abstract class FocusBehaviorBase : Behavior<FrameworkElement>

{

  protected abstract DependencyProperty GetSourceProperty();

 

 

  protected override void OnAttached()

  {

    var focusController = AssociatedObject.DataContext as IFocusController;

    if(focusController == null) return;

 

    var elem = AssociatedObject as UIElement;

    var handler = new FocusControl.FocusControlHandler(elem, GetSourceProperty());

    focusController.MoveFocus += handler.HandleMoveFocus;

  }

}

 

 

This already covers the scenarios in the sample application, allowing you to use regular bindings, and simply drop a behavior on the controls you want to switch focus. Certainly nice from a designer's point of view :)

Peter O'Hanlon

unread,
Mar 16, 2010, 8:04:09 AM3/16/10
to wpf-di...@googlegroups.com
Ooohhhh. Very nice, very nice indeed. I really need to get more into Blend behaviours.
--
Peter O'Hanlon

Bill Kempf

unread,
Mar 16, 2010, 8:13:13 AM3/16/10
to wpf-di...@googlegroups.com
I don't have time to go over the code in depth to understand if
there's something new to leverage here (Josh's comment about not
wanting to use the Name property makes me suspect there may be some
magic here that I can leverage), but I must say that this is one
scenario where I really like Onyx's concept of using services. There's
no need for the XAML to be marked up with attached properties or
Behaviors. Onyx already has this with the IFocusSuggested service.

--
Quidquid latine dictum sit, altum sonatur.
- Whatever is said in Latin sounds profound.

War is peace. Freedom is slavery. Bugs are features.

Sacha Barber

unread,
Mar 16, 2010, 8:15:26 AM3/16/10
to wpf-di...@googlegroups.com
Yep like it.
--
Sacha Barber
sacha....@gmail.com

Marlon Grech

unread,
Mar 16, 2010, 9:34:57 AM3/16/10
to wpf-di...@googlegroups.com
Interesting and very cool way of using markup extension indeed.... But wouldn't this make it that you can only set the focus when there is an error?

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Sacha Barber

unread,
Mar 16, 2010, 9:38:54 AM3/16/10
to wpf-di...@googlegroups.com
I think that is what Joshs original code did matey!!!
--
Sacha Barber
sacha....@gmail.com

Marlon Grech

unread,
Mar 16, 2010, 9:53:51 AM3/16/10
to wpf-di...@googlegroups.com
true but sometimes you want more then that right...

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Zhou Yong

unread,
Mar 16, 2010, 9:57:56 AM3/16/10
to wpf-di...@googlegroups.com
This is one typical scenario in which I think pure MVVM approach will not make a good solution, MVVM + MVP like Onyx is a more natural approach to take, and you could even easily mock up the focus management when unit testing the VM.

Thumbs up for Bill's work

MarocZ

Josh Smith

unread,
Mar 16, 2010, 9:58:11 AM3/16/10
to wpf-di...@googlegroups.com
Slick!  I wonder if offering a custom binding and blend behaviors is the right way to go...

Josh Smith

unread,
Mar 16, 2010, 9:59:43 AM3/16/10
to wpf-di...@googlegroups.com
No, it's not restricted to when there's an error.  The demo app happens to use this focus management stuff to move focus to an invalid control, but that's not a requirement.

Josh Smith

unread,
Mar 16, 2010, 10:02:24 AM3/16/10
to wpf-di...@googlegroups.com
Philipp, that binding decorator class is exactly what I need.  Thanks!

Josh Smith

unread,
Mar 16, 2010, 11:24:05 AM3/16/10
to wpf-di...@googlegroups.com
I've blogged about the custom binding approach, and gave proper credit to the Disciples. :)


Josh

Peter O'Hanlon

unread,
Mar 16, 2010, 11:40:18 AM3/16/10
to wpf-di...@googlegroups.com
Good stuff Josh. BTW, you can make your codesnippets look more codey by wrapping them in [sourcecode language='csharp'][/sourcecode] tags for C# and [sourcecode language='xml'][/sourcecode] for XAML.
--
Peter O'Hanlon

Josh Smith

unread,
Mar 16, 2010, 11:47:00 AM3/16/10
to wpf-di...@googlegroups.com
I just tried it, but WordPress kept stripping those tags out. This is why I normally use screenshots of code, instead of plaintext.  :(

Sacha Barber

unread,
Mar 16, 2010, 12:11:10 PM3/16/10
to wpf-di...@googlegroups.com
Have I have tried that too and wordpress strips it for me too. 
--
Sacha Barber
sacha....@gmail.com

Philipp Sumi

unread,
Mar 16, 2010, 12:15:59 PM3/16/10
to wpf-di...@googlegroups.com

Josh,

 

Glad you could use it the helper class - cheers on the article :)

I was thinking about quickly publishing the alternative behavior approach, focusing on the behaviors as an alternative. Would that be okay for you if I just published it as an derivative of your legwork (including your VM and helper classes)?

 

Cheers,

Philipp

Josh Smith

unread,
Mar 16, 2010, 12:38:34 PM3/16/10
to wpf-di...@googlegroups.com
No problem, Philipp.

Josh Smith

unread,
Mar 16, 2010, 1:43:30 PM3/16/10
to wpf-di...@googlegroups.com
Hey Philipp...I changed some names in the code that I posted on my blog.  IFocusController became IFocusMover, FocusControl became FocusController, etc.  You might want to get the latest code, so that our blogs are in sync.

Josh

Philipp Sumi

unread,
Mar 16, 2010, 2:38:43 PM3/16/10
to wpf-di...@googlegroups.com

Josh,

 

I've already downloaded the sample from your blog and will make the post tomorrow (I like the cleanup and changed naming scheme, btw). I'll have to make the private class internal in order to get to it, but apart from that, it's ready to be used :)

 

Another thing - while looking at the source, I noticed that my decorator class was still the original version as it was published back in 2008. This one works, but it's missing the additional properties that were added with .NET 3.5 SP1 (e.g. StringFormat). I've updated the download in the mean time, so if you wanted to include the latest version, you could get it here: http://www.hardcodet.net/uploads/2008/04/custom-bindings.zip

Josh Smith

unread,
Mar 16, 2010, 2:46:22 PM3/16/10
to wpf-di...@googlegroups.com
Good to know, thanks!

Josh Smith

unread,
Mar 17, 2010, 12:07:36 AM3/17/10
to wpf-di...@googlegroups.com
Philipp...I've updated the source code to use your enhanced binding decorator...but I also fixed a bug pointed out by someone in a comment.  http://joshsmithonwpf.wordpress.com/2010/03/16/control-input-focus-from-viewmodel-objects/

Josh

Philipp Sumi

unread,
Mar 17, 2010, 4:47:25 AM3/17/10
to wpf-di...@googlegroups.com

Josh,

 

Thanks for the update - I updated my sources accordingly. Regarding the decorator - I think you got the same version one again (it's part of the download in order to keep compatibility with pre-SP1). Maybe your proxy played a foul one on you (the new download contains an encapsulated ZIP file with the old sources, the updated decorator class and a readme file).

 

Another thing that caught my eye: You could simplify the declaration if you set the ValidatesOnDataErrors to true in the constructor of the FocusBinding class. Like this the property would default to true, and users could simply declare their binding like this:

 

<TextBox Text="{jas:FocusBinding FirstName}" />

 

With the current implementation, ValidatesOnDataErrors defaults to false, so one has to declare it explicitly. Minor thing, however.

Philipp Sumi

unread,
Mar 17, 2010, 7:27:30 AM3/17/10
to wpf-di...@googlegroups.com

Posted the alternative configuration approach via Blend Behaviors:

http://www.hardcodet.net/2010/03/input-focus-from-the-view-model-configured-via-blend-behaviors

 

Josh, in case you'd like me to add/change something, just drop me a note.

 

Now on to Sacha's article - it looks like quite a reading :)

 

Cheers,

Philipp

 

 

 

 

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Josh Smith


Sent: Mittwoch, 17. März 2010 05:08

Sacha Barber

unread,
Mar 17, 2010, 7:45:54 AM3/17/10
to wpf-di...@googlegroups.com
Once you collapse Dr WPF excellent ObserableDictionary<T>, its an ok'ish size read.
--
Sacha Barber
sacha....@gmail.com

Josh Smith

unread,
Mar 17, 2010, 10:56:05 AM3/17/10
to wpf-di...@googlegroups.com
Great post, Philipp.  Your approach is superior to mine because it works in Silverlight, too (I think...).  Nice job!

Pavan Podila

unread,
Mar 17, 2010, 11:30:20 AM3/17/10
to WPF Disciples
Philipp,
Just curious if this could be an Action instead of a Behavior.
I have built my own SetFocusAction class that works differently for
different controls. You could think of it as a base SetFocusAction
class. The only reason why I like an Action over a Behavior is because
I can control when the focus needs to be set. I typically do it in the
Loaded event for a UserControl or when some transition leads to a
previously loaded page. In those cases, I have an EventTrigger which
is wired to a SetFocusAction.

I think the Action approach gives a little more control. What do you
and others think of this approach ?

On Mar 17, 10:56 am, Josh Smith <flappleja...@gmail.com> wrote:
> Great post, Philipp.  Your approach is superior to mine because it works in
> Silverlight, too (I think...).  Nice job!
>

> On Wed, Mar 17, 2010 at 4:27 AM, Philipp Sumi <phil...@hardcodet.net> wrote:
> >  Posted the alternative configuration approach via Blend Behaviors:
>

> >http://www.hardcodet.net/2010/03/input-focus-from-the-view-model-conf...


>
> > Josh, in case you'd like me to add/change something, just drop me a note.
>
> > Now on to Sacha's article - it looks like quite a reading :)
>
> > Cheers,
>
> > Philipp
>

> > *From:* wpf-di...@googlegroups.com [mailto:
> > wpf-di...@googlegroups.com] *On Behalf Of *Josh Smith
>
> > *Sent:* Mittwoch, 17. März 2010 05:08
> > *To:* wpf-di...@googlegroups.com
> > *Subject:* Re: [WPF Disciples] Re: Controlling focus from ViewModel


> > objects
>
> > Philipp...I've updated the source code to use your enhanced binding
> > decorator...but I also fixed a bug pointed out by someone in a comment.

> >http://joshsmithonwpf.wordpress.com/2010/03/16/control-input-focus-fr...
>
> > Josh
>
> > On Tue, Mar 16, 2010 at 11:38 AM, Philipp Sumi <phil...@hardcodet.net>


> > wrote:
>
> > Josh,
>
> > I've already downloaded the sample from your blog and will make the post
> > tomorrow (I like the cleanup and changed naming scheme, btw). I'll have to
> > make the private class internal in order to get to it, but apart from that,
> > it's ready to be used :)
>
> > Another thing - while looking at the source, I noticed that my decorator
> > class was still the original version as it was published back in 2008. This
> > one works, but it's missing the additional properties that were added with
> > .NET 3.5 SP1 (e.g. StringFormat). I've updated the download in the mean
> > time, so if you wanted to include the latest version, you could get it here:
> >http://www.hardcodet.net/uploads/2008/04/custom-bindings.zip
>
> > Cheers,
>
> > Philipp
>

> > *From:* wpf-di...@googlegroups.com [mailto:
> > wpf-di...@googlegroups.com] *On Behalf Of *Josh Smith
> > *Sent:* Dienstag, 16. März 2010 18:44
>
> > *To:* wpf-di...@googlegroups.com
> > *Subject:* Re: [WPF Disciples] Re: Controlling focus from ViewModel


> > objects
>
> > Hey Philipp...I changed some names in the code that I posted on my blog.
> >  IFocusController became IFocusMover, FocusControl became FocusController,
> > etc.  You might want to get the latest code, so that our blogs are in sync.
>
> > Josh
>

> > On Tue, Mar 16, 2010 at 9:38 AM, Josh Smith <flappleja...@gmail.com>
> > wrote:
>
> > No problem, Philipp.
>
> > On Tue, Mar 16, 2010 at 9:15 AM, Philipp Sumi <phil...@hardcodet.net>


> > wrote:
>
> > Josh,
>
> > Glad you could use it the helper class - cheers on the article :)
>
> > I was thinking about quickly publishing the alternative behavior approach,
> > focusing on the behaviors as an alternative. Would that be okay for you if I
> > just published it as an derivative of your legwork (including your VM and
> > helper classes)?
>
> > Cheers,
>
> > Philipp
>

> > *From:* wpf-di...@googlegroups.com [mailto:
> > wpf-di...@googlegroups.com] *On Behalf Of *Josh Smith
> > *Sent:* Dienstag, 16. März 2010 15:02
>
> > *To:* wpf-di...@googlegroups.com
> > *Subject:* Re: [WPF Disciples] Re: Controlling focus from ViewModel


> > objects
>
> > Philipp, that binding decorator class is exactly what I need.  Thanks!
>

> > On Tue, Mar 16, 2010 at 1:23 AM, Philipp Sumi <phil...@hardcodet.net>


> > wrote:
>
> > Very nice approach, Josh - markup extensions are one of the really
> > underestimated tools in a WPF developer's toolbox. In case you want to save
> > yourself the plumbing of all the binding properties, you can take the source
> > of this decorator class here - I'm using that one quite often for similar
> > scenarios, but encapsulates the whole binding stuff in a base class:
> >http://www.hardcodet.net/2008/04/wpf-custom-binding-class
>
> > However, maybe one could solve the problem more designer (less XAML)
> > friendly using Blend behaviors? I gonna have to check that out.
>

> > *From:* wpf-di...@googlegroups.com [mailto:
> > wpf-di...@googlegroups.com] *On Behalf Of *Josh Smith
> > *Sent:* Dienstag, 16. März 2010 04:41
> > *To:* wpf-di...@googlegroups.com
> > *Subject:* Re: [WPF Disciples] Re: Controlling focus from ViewModel


> > objects
>
> > On second thought, ProvideValue should check if the Binding property is
> > null, and act like a {Binding} if it is:
>
> > public override object ProvideValue(IServiceProvider serviceProvider)
>
> > {
>
> >     var provideValueTarget =
> > serviceProvider.GetService(typeof(IProvideValueTarget)) as
> > IProvideValueTarget;
>
> >     if (provideValueTarget != null)
>
> >     {
>
> >         var element = provideValueTarget.TargetObject as DependencyObject;
>
> >         var property = provideValueTarget.TargetProperty as
> > DependencyProperty;
>
> >         FocusControl.SetFocusableProperty(element, property);
>
> >     }
>

> >     *if (this.Binding == null)*
>
> > *        this.Binding = new Binding();*
>
> >     return this.Binding.ProvideValue(serviceProvider);
>
> > }
>
> > On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com>

> > On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>

> > On Mon, Mar 15, 2010 at 3:22 PM, Marlon Grech <marlongr...@gmail.com>


> > wrote:
>
> > to make this less magic one could create an interface and make the Attached
> > Behaviour set a property on that interface.... yet having said that then why
> > not go to Take 1.... mmmm.... aa well... its good to have option now all you
> > need to do is pick one :)
>
> > But yea I think the first option is probably ideal.. the other options are
> > there because WPF is awesome and you can do crazy shit.... oww my beer is
> > talking now.. :)
>
> > Regards
> > Marlon

> > WPF Blog -http://marlongrech.wordpress.com/
> > Microsoft MVP for Client App
>

> > On Mon, Mar 15, 2010 at 10:50 PM, Marlon Grech <marlongr...@gmail.com>


> > wrote:
>
> > here is take 3 :)
>
> > P.S I am on my second Pint so excuse any stupid mistakes :D
>
> > The idea is that the Attached behavior injects a command that the ViewModel
> > can use to get an element focused. (it is still using the namescope idea).
>
> > This is what the ViewModel does
> > ICommand focusCommand;
> >         public ICommand FocusCommand
> >         {
> >             get { return focusCommand; }
> >             set
> >             {
> >                 focusCommand = value;
> >                 OnPropertyChanged("FocusCommand");
> >             }
> >         }
>
> >         public ICommand Save { get; private set; }
>
> >         public MyViewModel()
> >         {
> >             Save = new RelayCommand(x =>
> >             {
> >                 if (FocusCommand.CanExecute("Name"))
> >                     FocusCommand.Execute("Name");
> >              }
>
> > So the ViewModel exposes a command property but never sets it.
>
> > Then in the View you work a bit of magic
> > <Grid
>

> ...
>
> read more »

Josh Smith

unread,
Mar 17, 2010, 11:47:30 AM3/17/10
to wpf-di...@googlegroups.com
Interesting comment, Pavan. The impetus behind all of this is to allow the VM objects to indirectly specify where input focus should go.  I don't see why that functionality would be considered an "action."  In my mind, it's a behavior of an element to react to VM requests for focus movement.  I don't see any trigger-based scenarios in which this functionality would be useful, but if you have one in mind, please do share!

Thanks,
Josh

Sacha Barber

unread,
Mar 17, 2010, 11:50:18 AM3/17/10
to wpf-di...@googlegroups.com
Like Josh said this whole thread is about VM controlling focus, I like both Josh/Philips/Marlons ideas, but can also see that a service AKA WPF Onyx IFocusSuggestor would work nicely too.
--
Sacha Barber
sacha....@gmail.com

Pavan Podila

unread,
Mar 17, 2010, 12:07:19 PM3/17/10
to WPF Disciples
Josh,
I typically use events coming from the VM as triggers for the
focus action. In my current app, I have a set of custom triggers,
which are invoked from a VM instance. Some of these triggers fire the
focus action when needed.

HTH.

On Mar 17, 11:47 am, Josh Smith <flappleja...@gmail.com> wrote:
> Interesting comment, Pavan. The impetus behind all of this is to allow the
> VM objects to indirectly specify where input focus should go.  I don't see
> why that functionality would be considered an "action."  In my mind, it's a
> behavior of an element to react to VM requests for focus movement.  I don't
> see any trigger-based scenarios in which this functionality would be useful,
> but if you have one in mind, please do share!
>
> Thanks,
> Josh
>

> ...
>
> read more »

Pavan Podila

unread,
Mar 17, 2010, 12:13:30 PM3/17/10
to WPF Disciples
BTW, I should mention that the VM doesn't have a reference to the
Trigger, rather the Trigger is bound to some events/properties on the
VM. It listens to some changes and then invokes all of the attached
Actions.

> ...
>
> read more »

Josh Smith

unread,
Mar 17, 2010, 12:18:44 PM3/17/10
to wpf-di...@googlegroups.com
I see.  That's a good example. :)

Pavan Podila

unread,
Mar 17, 2010, 12:30:20 PM3/17/10
to WPF Disciples
Now that you say its "good", let me give a concrete example:

On the login screen, there is a SetFocusAction on the Username
textbox. The trigger for this action is either a Loaded event (which
happens when you launch the app and bring up the Login screen) or a
"LogOut" event that is fired by the AuthenticationService. When the
LogOut event is fired, the previously hidden Login screen is brought
up and focus is set on the Username textbox. This is an example of a
Trigger listening to an event on the VM (in my case an event on the
Root VM). You can also make this into a property like IsLoggedIn and
bind to it in the Trigger. When it changes to false, you can bring up
the login screen and set focus on it. We found the event-approach was
superior because of an edge case with the bool property (how do you
deal with IsLoggedIn being false the first time ?)

Hope that is more "real world" :)

On Mar 17, 12:18 pm, Josh Smith <flappleja...@gmail.com> wrote:
> I see.  That's a good example. :)
>

> ...
>
> read more »

Philipp Sumi

unread,
Mar 17, 2010, 12:39:18 PM3/17/10
to wpf-di...@googlegroups.com

Thanks Josh! However, I wouldn't call it superior despite the SL compatibility - it's really just a different approach that fits another environment. I can't even do "hello world" without writing a custom markup extension, and would prefer that approach over behaviors at any time when using in a VS environment.

Philipp Sumi

unread,
Mar 17, 2010, 12:42:37 PM3/17/10
to wpf-di...@googlegroups.com
Pavan,

I like the approach, not the least because you can throw targeted actions into the mix. I've been exploring actions and wrapper classes on the VM (blog post coming soon) recently, and found the technique very useful. However, you'll have to pay the price of your VM classes being dependency objects, wouldn't they?

Pavan Podila

unread,
Mar 17, 2010, 12:49:00 PM3/17/10
to WPF Disciples
Philipp,
I don't see why VMs should be DependencyObjects. They are
regular POCOs with INPC implemented on them. It is the Trigger than
has the binding to these VM instances and Triggers are already
DependencyObjects so Binding works on them.
Does that clarify ?

> ...
>
> read more »

Philipp Sumi

unread,
Mar 17, 2010, 12:54:35 PM3/17/10
to wpf-di...@googlegroups.com
*duh*, I was mixing up use cases. You're right of course - you don't target the VM.

Daniel Vaughan

unread,
Mar 17, 2010, 7:07:11 PM3/17/10
to WPF Disciples
Great work guys.
This focus switching reminds me a little of the stuff I did with
Perceptor last year. Forcibly switching focus can feel non-
deterministic at times that’s for sure.
An alternative approach, for validation errors, might be something
like Perceptor, in that it could quite easily be taught to recognize
what an invalid data context looks like, and shift focus accordingly.
Perceptor is a prototype, and would need further work to be usable in
production. But it’s another way. It uses a top level attached
property and then indexes all IInputControls. Apologies if it seems
like I’m pushing my own stuff, I don’t mean to. There’s some overlap
that’s all.
Anyway, great work again guys.

http://www.codeproject.com/KB/smart/Perceptor.aspx

> ...
>
> read more »

Josh Smith

unread,
Mar 17, 2010, 7:10:23 PM3/17/10
to wpf-di...@googlegroups.com
And thus SkyNet was born...

Daniel Vaughan

unread,
Mar 17, 2010, 7:17:20 PM3/17/10
to WPF Disciples
haha

Just like the 'Advanced Dawson's Creek Trapper Keeper Ultra Keeper
Futura S 2000'

On Mar 18, 12:10 am, Josh Smith <flappleja...@gmail.com> wrote:
> And thus SkyNet was born...
>

> ...
>
> read more »

Josh Smith

unread,
Mar 17, 2010, 11:23:54 PM3/17/10
to wpf-di...@googlegroups.com
Can I get that with a titanium grip?

Karl Shifflett

unread,
Apr 1, 2010, 9:48:42 PM4/1/10
to wpf-di...@googlegroups.com

Josh & Philipp,

 

Just had time to study the set focus from ViewModel work you both did.  Very nice and thanks for sharing this.

 

Just today, I had a requirement to do this in WPF & SL.

 

Thanks again!

 

Karl

Reply all
Reply to author
Forward
0 new messages