I tried with a minimal application, just a textbox and a button. The button is binded to a RelayCommand instance, and the CanExecute method just return true or false with a random. The textbox text is binded with a string property.
What's making me mad is that the CanExecute method is "always" called: a change of the element focused, a key pressed in the textbox, it seems that everything fires a call to my CanExecute method.
Is this a "feature" of the mvvm light toolkit? Does this happen in a "normal" wpf application?
Yes, I know, I think I should know more about the commandind system in wpf... ;-)
Thanks for answers!
David
CanExecute is used to determine if the current state allows the command to execute. This is usually tied to the IsEnabled property to disable the command.
This should also be tied to a property on your ViewModel that indicates if the current view state allows executing.
It is tied to any event trigger on the hosting window, since any event could cause a change to the CanExecute state.
This link confirms it is fired on any event in the hosting window.
http://robburke.net/2008/04/23/wpf-command-pattern-when-does-it-query-canexecute/
Why do you think it being called all the time is an issue? As long as you don't have any intense logic in the bound property it should be fine.
Related
I have properties on my VisualState that I set their value on the Init method on the VisualState from my WebApi.
When I navigate to this page to press back to return to this this page the Init method is not called again.
How can I update the VisualState every time the page appears if by navigate on back button press, I'm thinking about using the on OnNavigated method on the viewmodel and set the visuelstate properties from there.
Should I do it, or there is another way?
If you want to do something, every time the View appears, you would use this override in the ViewModel.
OnAppearing
If you want it to run, only the first time it is view, then you use
OnNavigated
I have an ObservableCollection I'm attempting to bind to a ListView. I create everything just fine. The collection has multiple items in it (checked from both ends of the binding in ModelState and VisualState, but the View is never updated. I went ahead and bound directly to the ModelState's piece and everything worked just fine.
I suspect the cause is that INotifyCollectionChanged is not being sent through the binding. Is this something I can fix or is this a bug?
The binding between VisualState and ModelState are only done at the top level property. Hence if you replaced the ObservableCollection with a new ObservableCollection, that would be propagated. But the Binding doesn't know anything about the properties, hence it's not going to know about the INotifyCollectionChanged.
But, the binding should just copy the reference value from ModelState to VisualState, hence they should both reference the same object, therefore, adding a value at either end, should show a value change at the other end, and a raise of the event.
I would try manually attaching to the event, to confirm it is being raised.
I'm coming from an ASP background and learning ASP.NET. I wanted to know whether AutoEventWireup property wireup the Control events also(like Button_Click) or just the Page events?
I read elsewhere in SO that if you set it to TRUE & also provide explicit event handlers, it'll be executed twice, Can you explain why this happens (since there is just 1 handler VS must recognize its already executed)?
Can you give Use Cases of setting it to False?
Would appreciate a code sample
Generally it is set to true, which means you do not need to wireup each even explicitly. You will set it to false when you want to use the same event handler for more than one controls/events. In that case you can explicitly wireup multiple events to single event handler. It controls all events. When you set the property to true and also wireup the events explicitly, .Net will fire the event twice, because delegate will be registered twice.
AutoEventWireup on the Page element works by looking for methods matching an expected signature and naming convention (i.e. Page_<event>). If found, the page framework will call the event-handlers directly before "raising" the event normally. This is why, if you register the event-handlers in code, they are effectively called twice.
This is quite different from how event handlers normally work. If you wrote code to register a handler with the same event twice, it will only be called once per event. This is because the event handlers are essentially a set of delegates and attempting to add a delegate to the same method is a no-op.
The AutoEventWireup behaviour only applies to events raised by the page. You won't get it for other controls, so they should be wired up manually, usually in a Page_Init or Page_Load event.
If you don't use AutoEventWireup (i.e. set it to "false"), you have to wire up the page event handlers yourself to get them to be called. This is what the Visual Studio designer does, since it generates event-registration code for you.
UPDATE : Figured it out..
The objects I was passing to the ValidatorHookupControl were'nt being set properly (were null). Now that they are, the messages are currectly dissapearing when the hooked up control looses it's focus.
ORIGINAL POST ..
Hi,
I have some ClientValidation controls that have ClientSideValidation methods which work fine when validating the page..
However, how can I make it so that when a certain control that a CustomValidators clientside method kicks in and udates the validation message depending on whether the validation has passed or not. (Like the RequiredFieldValidator or RegExValidator).
My Customvalidators do not have their ControltoValidate properties set as some of them depend on multiple controls.
I don't want any postbacks (full or partial).
I have tried..
Adding an onchange attribute on dropdowns, radioboxes and checkboxes that call a helper clientside method which calls Page_ClientValidate('GroupName'), then setting window.location back to the control in question (as it went back to top of screen).
Using this method the args.IsValid is still being set by the ClientSideValidation method.
And I have tried ValidatorHookupControl (control, validator) but that doesn't seem to work either.
Any thoughts..?
My bad, was passing null objects into the ValidatorHookupControl method.
Works now. Doh!
Is there not an event that occurs only when there has been some sort of visual change to an object. So for example if it were a video or animated object it would be firing as often as EnterFrame. However, if it were some sort of input control just sitting there doing nothing visually, then the event wouldn't fire until the visual state changed as a result of some sort of user input for example.
I've tried dozen's of events and none of them seem to fire this way.
For visual components about the closest you're going to get is FlexEvent.UPDATE_COMPLETE which will fire after an object has it's commitProperties(), measure() and updateDisplayList() called. If you're subclassing the component, then overriding updateDisplayList() and handling (or throwing you're own event) in there would ensure that you're only getting the event when something visual changes.
For video, you'll want to listen to VideoEvent.PLAYHEAD_UPDATE