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.
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.
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.. :)
> 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 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?
>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>> 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
>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber <sacha.bar...@gmail.com>wrote:
>>>>> I do not like the idea of the Binding not firing.
>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>>> 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
>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>> Same here.
>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>> I prefer option 1 actually
>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>> P.S sorry for ugly code and all that but the code I produced is >>>>>>>>> just to show you guys the idea ....
>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>> 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
>>>>>>>>>> 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
>>>>>>>>>> On Mon, Mar 15, 2010 at 8:25 PM, Daniel Vaughan < >>>>>>>>>> dbvaug...@gmail.com> wrote:
>>>>>>>>>>> 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...).
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.
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.
On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> wrote: > 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.
> 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
> 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.. :)
>> 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 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?
>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>> 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
>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber <sacha.bar...@gmail.com >>>>> > wrote:
>>>>>> I do not like the idea of the Binding not firing.
>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>>>> 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
>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>> Same here.
>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>> I prefer option 1 actually
>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>> 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
>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>> 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
>>>>>>>>>>> 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
>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:25 PM, Daniel Vaughan < >>>>>>>>>>> dbvaug...@gmail.com> wrote:
>>>>>>>>>>>> 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:
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();*
} On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> wrote: > 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.
> 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
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>wrote:
>> 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.
>> 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
>> 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.. :)
>>> 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 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?
>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>> 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
>>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber < >>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>> I do not like the idea of the Binding not firing.
>>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech <marlongr...@gmail.com >>>>>>> > wrote:
>>>>>>>> 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
>>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>>> Same here.
>>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>>> I prefer option 1 actually
>>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>> 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
>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>> 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
>>>>>>>>>>>> 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
>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:25 PM, Daniel Vaughan < >>>>>>>>>>>> dbvaug...@gmail.com> wrote:
>>>>>>>>>>>>> Good thinking Marlon. As Pete said, very innovative.
On Tue, Mar 16, 2010 at 3:40 AM, Josh Smith <flappleja...@gmail.com> wrote: > 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); > }
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com>wrote:
>> 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.
>> 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
>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>wrote:
>>> 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.
>>> 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
>>> 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.. :)
>>>> 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 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?
>>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>>> 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
>>>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber < >>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>> I do not like the idea of the Binding not firing.
>>>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech < >>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>> 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
>>>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>>>> Same here.
>>>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>>>> I prefer option 1 actually
>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>> 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
>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>>> 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
>>>>>>>>>>>>> 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?
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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 04:41 To: wpf-disciples@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();
} On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
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.. :)
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 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?
On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> wrote:
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
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?
> 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
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); } }
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 :)
From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Philipp Sumi Sent: Dienstag, 16. März 2010 10:24 To: wpf-disciples@googlegroups.com Subject: RE: [WPF Disciples] Re: Controlling focus from ViewModel objects
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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 04:41 To: wpf-disciples@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();
} On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
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.. :)
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 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?
On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> wrote:
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
> 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>
> 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
> 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>
> 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 :)
> *From:* wpf-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Philipp Sumi > *Sent:* Dienstag, 16. März 2010 10:24
> 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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 04:41 > *To:* wpf-disciples@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;
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> If BindingBase.ProvideValue wasn't sealed, I could have just overridden > that method instead of creating a wrapper markup extension. Oh well.
> Josh
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> 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
> 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.. :)
> 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 focusStuff:FocusedBehaviourTake3.HandleFocusElement="True"
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.
On Tue, Mar 16, 2010 at 6:58 AM, Philipp Sumi <phil...@hardcodet.net> wrote: > Ok, I did a quick dive into Blend behaviors and came up with an alternative > (but not necessarily better) approach.
> 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>
> 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
> 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>
> 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 :)
> From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] > On Behalf Of Philipp Sumi > Sent: Dienstag, 16. März 2010 10:24
> To: wpf-disciples@googlegroups.com > Subject: RE: [WPF Disciples] Re: Controlling focus from ViewModel objects
> 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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] > On Behalf Of Josh Smith > Sent: Dienstag, 16. März 2010 04:41 > To: wpf-disciples@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;
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> wrote:
> 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.
> If BindingBase.ProvideValue wasn't sealed, I could have just overridden that > method instead of creating a wrapper markup extension. Oh well.
> Josh
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> wrote:
> 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.
> 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
> 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.. :)
> 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;
>> 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>
>> 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
>> 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>
>> 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 :)
>> *From:* wpf-disciples@googlegroups.com [mailto: >> wpf-disciples@googlegroups.com] *On Behalf Of *Philipp Sumi >> *Sent:* Dienstag, 16. März 2010 10:24
>> 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-disciples@googlegroups.com [mailto: >> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >> *Sent:* Dienstag, 16. März 2010 04:41 >> *To:* wpf-disciples@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;
>> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> >> wrote:
>> 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.
>> If BindingBase.ProvideValue wasn't sealed, I could have just overridden >> that method instead of creating a wrapper markup extension. Oh well.
>> Josh
>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> >> wrote:
>> 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.
>> 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
>> 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.. :)
>> 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;
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
On Tue, Mar 16, 2010 at 3:38 AM, Josh Smith <flappleja...@gmail.com> wrote: > 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.
> 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
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>wrote:
>> 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.
>> 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
>> 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.. :)
>>> 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 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?
>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>> 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
>>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber < >>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>> I do not like the idea of the Binding not firing.
>>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech <marlongr...@gmail.com >>>>>>> > wrote:
>>>>>>>> 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
>>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>>> Same here.
>>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>>> I prefer option 1 actually
>>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>> 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
>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>> 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
>>>>>>>>>>>> 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
>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:25 PM, Daniel Vaughan < >>>>>>>>>>>> dbvaug...@gmail.com> wrote:
>>>>>>>>>>>>> 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.
On Tue, Mar 16, 2010 at 1:34 PM, Marlon Grech <marlongr...@gmail.com> wrote: > 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?
> On Tue, Mar 16, 2010 at 3:38 AM, Josh Smith <flappleja...@gmail.com>wrote:
>> 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.
>> 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
>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>wrote:
>>> 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.
>>> 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
>>> 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.. :)
>>>> 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 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?
>>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>>> 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
>>>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber < >>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>> I do not like the idea of the Binding not firing.
>>>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech < >>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>> 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
>>>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>>>> Same here.
>>>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>>>> I prefer option 1 actually
>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>> 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
>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>>> 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
>>>>>>>>>>>>> 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
>>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:25 PM, Daniel Vaughan < >>>>>>>>>>>>> dbvaug...@gmail.com> wrote:
>>>>>>>>>>>>>> Good thinking Marlon. As Pete said, very innovative.
>>>>>>>>>>>>>> On Mar 15, 7:33 pm, Marlon Grech <marlongr...@gmail.com>
> I think that is what Joshs original code did matey!!!
> On Tue, Mar 16, 2010 at 1:34 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>> 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?
>> On Tue, Mar 16, 2010 at 3:38 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>> 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.
>>> 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
>>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>wrote:
>>>> 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.
>>>> 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
>>>> 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.. :)
>>>>> 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 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?
>>>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com >>>>>> > wrote:
>>>>>>> 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
>>>>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber < >>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>> I do not like the idea of the Binding not firing.
>>>>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech < >>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>> 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
>>>>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>>>>> Same here.
>>>>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>>>>> I prefer option 1 actually
>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>>> 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
>>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>>>> 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
>>>>>>>>>>>>>> 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?
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.
On Tue, Mar 16, 2010 at 3:58 AM, Philipp Sumi <phil...@hardcodet.net> wrote: > Ok, I did a quick dive into Blend behaviors and came up with an > alternative (but not necessarily better) approach.
> 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>
> 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
> 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>
> 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 :)
> *From:* wpf-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Philipp Sumi > *Sent:* Dienstag, 16. März 2010 10:24
> 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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 04:41 > *To:* wpf-disciples@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;
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> If BindingBase.ProvideValue wasn't sealed, I could have just overridden > that method instead of creating a wrapper markup extension. Oh well.
> Josh
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> 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
> 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.. :)
> 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 focusStuff:FocusedBehaviourTake3.HandleFocusElement="True"
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.
On Tue, Mar 16, 2010 at 5:34 AM, Marlon Grech <marlongr...@gmail.com> wrote: > 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?
> On Tue, Mar 16, 2010 at 3:38 AM, Josh Smith <flappleja...@gmail.com>wrote:
>> 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.
>> 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
>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com>wrote:
>>> 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.
>>> 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
>>> 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.. :)
>>>> 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 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?
>>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com>wrote:
>>>>>> 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
>>>>>>> On Mon, Mar 15, 2010 at 10:04 PM, Sacha Barber < >>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>> I do not like the idea of the Binding not firing.
>>>>>>>> On Mon, Mar 15, 2010 at 9:56 PM, Marlon Grech < >>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>> 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
>>>>>>>>> On Mon, Mar 15, 2010 at 9:20 PM, Peter O'Hanlon < >>>>>>>>> pete.ohan...@gmail.com> wrote:
>>>>>>>>>> Same here.
>>>>>>>>>> On Mon, Mar 15, 2010 at 9:18 PM, Sacha Barber < >>>>>>>>>> sacha.bar...@gmail.com> wrote:
>>>>>>>>>>> I prefer option 1 actually
>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:43 PM, Marlon Grech < >>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>> 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
>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:42 PM, Marlon Grech < >>>>>>>>>>>> marlongr...@gmail.com> wrote:
>>>>>>>>>>>>> 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
>>>>>>>>>>>>> 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
>>>>>>>>>>>>> On Mon, Mar 15, 2010 at 8:25 PM, Daniel Vaughan < >>>>>>>>>>>>> dbvaug...@gmail.com> wrote:
>>>>>>>>>>>>>> Good thinking Marlon. As Pete said,
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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 04:41 > *To:* wpf-disciples@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;
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> If BindingBase.ProvideValue wasn't sealed, I could have just overridden > that method instead of creating a wrapper markup extension. Oh well.
> Josh
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> 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
> 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.. :)
> 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 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?
> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> > wrote:
> 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
> 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?
On Tue, Mar 16, 2010 at 6:02 AM, Josh Smith <flappleja...@gmail.com> wrote: > 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-disciples@googlegroups.com [mailto: >> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >> *Sent:* Dienstag, 16. März 2010 04:41 >> *To:* wpf-disciples@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;
>> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> >> wrote:
>> 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.
>> If BindingBase.ProvideValue wasn't sealed, I could have just overridden >> that method instead of creating a wrapper markup extension. Oh well.
>> Josh
>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> >> wrote:
>> 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.
>> 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
>> 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.. :)
>> 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 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?
>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> >> wrote:
>> 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
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.
On Tue, Mar 16, 2010 at 3:24 PM, Josh Smith <flappleja...@gmail.com> wrote: > I've blogged about the custom binding approach, and gave proper credit to > the Disciples. :)
> On Tue, Mar 16, 2010 at 6:02 AM, Josh Smith <flappleja...@gmail.com>wrote:
>> 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-disciples@googlegroups.com [mailto: >>> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >>> *Sent:* Dienstag, 16. März 2010 04:41 >>> *To:* wpf-disciples@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;
>>> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> >>> wrote:
>>> 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.
>>> If BindingBase.ProvideValue wasn't sealed, I could have just overridden >>> that method instead of creating a wrapper markup extension. Oh well.
>>> Josh
>>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> >>> wrote:
>>> 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.
>>> 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
>>> 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.. :)
>>> 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 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?
>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> >>> wrote:
>>> 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
> 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.
> On Tue, Mar 16, 2010 at 3:24 PM, Josh Smith <flappleja...@gmail.com>wrote:
>> I've blogged about the custom binding approach, and gave proper credit to >> the Disciples. :)
>> On Tue, Mar 16, 2010 at 6:02 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>> 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-disciples@googlegroups.com [mailto: >>>> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >>>> *Sent:* Dienstag, 16. März 2010 04:41 >>>> *To:* wpf-disciples@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;
>>>> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> >>>> wrote:
>>>> 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.
>>>> If BindingBase.ProvideValue wasn't sealed, I could have just overridden >>>> that method instead of creating a wrapper markup extension. Oh well.
>>>> Josh
>>>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> >>>> wrote:
>>>> 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.
>>>> 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
>>>> 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.. :)
>>>> 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 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?
>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> >>>> wrote:
>>>> 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
On Tue, Mar 16, 2010 at 3:47 PM, Josh Smith <flappleja...@gmail.com> wrote: > I just tried it, but WordPress kept stripping those tags out. This is why I > normally use screenshots of code, instead of plaintext. :(
> On Tue, Mar 16, 2010 at 7:40 AM, Peter O'Hanlon <pete.ohan...@gmail.com>wrote:
>> 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.
>> On Tue, Mar 16, 2010 at 3:24 PM, Josh Smith <flappleja...@gmail.com>wrote:
>>> I've blogged about the custom binding approach, and gave proper credit to >>> the Disciples. :)
>>> On Tue, Mar 16, 2010 at 6:02 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>> 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-disciples@googlegroups.com [mailto: >>>>> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >>>>> *Sent:* Dienstag, 16. März 2010 04:41 >>>>> *To:* wpf-disciples@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;
>>>>> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> >>>>> wrote:
>>>>> 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.
>>>>> If BindingBase.ProvideValue wasn't sealed, I could have just overridden >>>>> that method instead of creating a wrapper markup extension. Oh well.
>>>>> Josh
>>>>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> >>>>> wrote:
>>>>> 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.
>>>>> 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
>>>>> 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.. :)
>>>>> 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 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?
>>>>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech < >>>>> marlongr...@gmail.com> wrote:
>>>>> 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
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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 15:02 To: wpf-disciples@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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 04:41 To: wpf-disciples@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();
} On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
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.. :)
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 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?
On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> wrote:
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
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?
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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 15:02
> 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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 04:41 > *To:* wpf-disciples@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;
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> If BindingBase.ProvideValue wasn't sealed, I could have just overridden > that method instead of creating a wrapper markup extension. Oh well.
> Josh
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> 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
> 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.. :)
> 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 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?
> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> > wrote:
> 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
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.
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-disciples@googlegroups.com [mailto: >> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >> *Sent:* Dienstag, 16. März 2010 15:02
>> 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-disciples@googlegroups.com [mailto: >> wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith >> *Sent:* Dienstag, 16. März 2010 04:41 >> *To:* wpf-disciples@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;
>> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> >> wrote:
>> 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.
>> If BindingBase.ProvideValue wasn't sealed, I could have just overridden >> that method instead of creating a wrapper markup extension. Oh well.
>> Josh
>> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> >> wrote:
>> 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.
>> 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
>> 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.. :)
>> 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 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?
>> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> >> wrote:
>> 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
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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 18:44 To: wpf-disciples@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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 15:02
To: wpf-disciples@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-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Dienstag, 16. März 2010 04:41 To: wpf-disciples@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();
} On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> wrote:
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.
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
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.. :)
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 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?
On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> wrote:
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
> 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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 18:44
> 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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 15:02
> 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-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Dienstag, 16. März 2010 04:41 > *To:* wpf-disciples@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;
> On Mon, Mar 15, 2010 at 7:38 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> If BindingBase.ProvideValue wasn't sealed, I could have just overridden > that method instead of creating a wrapper markup extension. Oh well.
> Josh
> On Mon, Mar 15, 2010 at 6:33 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> 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.
> 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
> 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.. :)
> 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 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?
> On Mon, Mar 15, 2010 at 10:08 PM, Marlon Grech <marlongr...@gmail.com> > wrote:
> 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