Handling Events from the Business Layer in XAML WPF - wpf

I am very new to WPF, and I have a very basic WPF question:
Suppose we have a custom dll with some business logic that fires events such as
ModemIsConnected. On the UI side (.xaml) there is a label that changes its value to OK once that event is fired. I would like to offload the event handling portion (changing label's status and other minor UI tweaks) to a designer. Is it possible to handle events in xaml without creating code-behind?
Thanks!

The simple answer is I don't believe it's possible. There are no doubt things you can do with data binding and the like, but then you're getting beyond the kind of thing you want a designer to be doing.
A couple of options:
Teach the designer the bare minimum of coding an event handler and calling a storyboard. With intellisense and the nice interaction between Blend / Visual Studio you could have someone up and running fairly quickly.
Have them create storyboard animations for any of the 'minor UI tweaks' you require, and then you can hook these up to the event and change your label text with only 3-5 lines of code.

You can have the designer do the UI side without them having to get their hands dirty with code. You could create a class that implements IPropertyNotifyChanged with a boolean property that changes as the modem state changes. The designer can then bind to that property and do fancy triggers, state changes etc etc from within the XAML and the binding system will handle "telling" the UI the value has changed.

Related

Lots of bindings, really slow, are binding active even if attached UIElement not visible?

I'm developing a WPF application that heavily relies on DataBinding.
Basically the app has several tabsheets each of which have ~50 elements using DataBinding to my ViewModel. Some of the binding are a bit complex with datatriggers and converters to display images based on binding results and so on.
Performance is good when I start the application, but as I navigate each of the tabsheets its getting slower and slower (and CPU usage increase). After I've navigate, lets say, 10 tabs, the application is almost unusuable, hanging for a couple of seconds everytime the binding sources fires de PropertyChanged events.
It seems as if binding targeted to visual elements that are not visible (because they are in a different tabsheet than the current one) are still processing, running the converter, and updating the visual control.
Is there any way to disable this? It would be an option to implement my own TabControl that disables every binding for non visible tabs, but havent found how to do this yet.
Any other suggestion would be appreciated!
As a side note, that may be important: every binding source raises its own PropertyChanged every ~5s that is the time we are reading the values from a device in the viewmodel. So, every 5s or so around 300 objects that implements INotifyPropertyChanged raise simultaneously the PropertyChanged event and at this instant is when the application freezes for a couple of seconds.
Due to the nature of the application, is not a option to slow down the update to anything more than 5s.
I am not MVVM but I thought in MVVM only the active tab was rendered.
In non MVVM what I do is for EVERY property I detect if it is the active tab and if not the active tab then I have it return nothing or a default value. TabControl has a SelectedIndex property.

VisualState Binding threading issue

I have an audio recording app in Windows Phone 7.
The app allows a user to play the recorded sounds.
I try to stick to MVVM guidelines where it is possible.
I have a play/stop button in a list of all recordings. Each recording has its own ViewModel, which, besides all, also controls the look of the corresponding play/stop button.
The button has a custom visual state defined in its' style.
The Visual State is bound to the ViewModel's property using the approach, shown here:
http://tdanemar.wordpress.com/2009/11/15/using-the-visualstatemanager-with-the-model-view-viewmodel-pattern-in-wpf-or-silverlight/
Having implemented this approach, whenever I want to change the look of the play/stop button, I need to set the public string property (named "PlayStopVisualState") in my ViewModel to either "PlayingState" or "Normal", and that will assign an appropriate visual state to my button.
The problem is that when user presses the play button, a SoundEffectInstance is created in a background thread, which plays the sound. The thread then waits for the playing to end. When the recording playing is over (I have to track it in the same background thread, or create another for just tracking SoundEffectInstance.State) I set the PlayStopVisualState property back to "Normal", but I get a cross-thread reference exception. Isn't MVVM specifically designed to allow developers to manipulate logical variables in a view model, and not having to worry about how the changes to them are reflected in a View?
I know that I need to do the adjustment of the PlayStopVisualState property in a Dispatcher thread in order for the problem to disappear, but this is just no right. It, from my point of view, defeats the whole purpose of MVVM, leaving only the organizational advantage.
Or am I doing something wrong? Thanks.
UPDATE:
I have worked around the problem by using
Deployment.Current.Dispatcher
but it seems to me as a very "ugly" solution, given that I almost all over have MVVM pattern followed.
Using the Dispatcher to reflect a UI-bound value is the correct way to do it, yes.
What you're forgetting is that your ViewModel is created on the UI thread. So any change to the ViewModel from a background thread, would a cross-thread operation.
You should consider if a background thread is really needed. , or if you could just schedule your action on the UI thread directly.

Microsoft Silverlight DataGrid custom ToolTip

I have SL3 DataGrid and need a tooltip on rows and different columns which has data that needs to be fetched from DataBase when user hovers over the tooltip.
I saw samples around
that helps use the current binding context or the static content for the tooltip.
But, how can I get a usercontrol shown in the tooltip which goes and fetches Database only when user brings up the tooltip
Also, is there a way to easily fit this into MVVM instead of having a lot of code on the code behind?
I don't think tooltips properly leverage databinding, or at least in the way I think is proper. If you are binding to a ViewModel property in your XAML tool tip declaration that is going to resolve immediately, which means the call will be made immediately. I suppose you could plumb in some attached property or some other logic to list to the tool tip opening event, and then do an async web service call.
From an MVVM perspective, the VM probably should not care why something wants the data, just that it needs to lazy load it. So you could have a property on the VM (or perhaps even in the Model object) that exposes the data, but lazy-loads the data the first time the property is called. When the async call comes back you just fire the PropertyChanged event on your VM or M which should be interfaced with INotifyPropertyChanged. Then your databinding in the View will pick up the change. The key to getting all this to run when the pop-up of the tooltip occurs is to not bind the data until the tool tip actually does pop-up. It might be worth your time to extend the tooltip to do this, or right your own container to sit inside a tooltip that does this late-databinding.

Dynamic animations, Commands and separation of concerns

Scenario: I have a (numeric) textbox, a button, and a label. When the button is clicked I'd like the label to "animate" to the numeric value in the textbox (like a spinning dial)
Given:
a) that animations in storyboards cannot have databindings (because they are not FrameworkElements)
b) the lack of triggers in Silverlight
What is the best, and with least coupling of the view model to the view's storyboard, way to update the target animation value and start the animation when the button is clicked?
Note: The scenario is conceptual, so don't concentrate on the specifics of 'animating' numbers or anything
If your goal is strictly to reduce the code-behind in the view I think that an attached behaviour on the Label would work for this. The attached behaviour on the label would expose the number to be animated to and when this number changes an animation (in code) would be run to animate from the old value to the new value.
One drawback is that your animation is now in code, unless you store a templated (just has fake values to start with) version of it in a resource file somewhere where you can load it as needed and replace the templated values.
This article from Josh Smith seems to be the authority on Attached Behaviours;
http://joshsmithonwpf.wordpress.com/2008/08/30/introduction-to-attached-behaviors/
I recently had to solve a similar problem in an MVVM application. My problem was that I needed to animate a container's height from zero to auto. Since Auto is a dynamic value I recognized that the animation (or storyboard) would need to be built (or manipulated) on demand. The solution that I put in place involved using view code-behind to update and fire the animation.
This isn't the most MVVM-friendly approach; however, animations in WPF can be tricky in XAML. Since this solution is really just a workaround for a XAML limitation it seems okay to tie the code directly to the view. Likewise, if the views were mocked then there would be no framework elements to animate, so it really wouldn't make sense to place this code on the VM side.
Does anybody have a better approach?

WPF Routed Events Across Element Tree Branches

I am wondering what the correct mechanism to enable communication between controls in WPF is. My goal is to not use conventional events and have to manually wire them up. The default behavior of routed commands (tunneling, bubbling) seems to be along the right lines but I guess I'm missing something.
Routed events are a new infrastructure provided by WPF which allows events to tunnel down the visual tree to the target element, or bubble up to the root element. When an event is raised, it “travels” up or down the visual tree invoking handlers for that event on any element subscribed to that event it encounters en route. Note that this tree traversal does not cover the entire visual tree, only the ancestral element
That is from this WPF Article
Using the image in the article, I want "Immediate Element #1" to initiate (raise) an event and then have "Immediate Element #2" handle that event. I'd like to achieve this without having to put any code in the "Root Element".
Basically fire an event (save, status updated, selection changed, etc..) from any where in my app, then have it be handled somewhere else with out the 2 parties knowing anything about each other. Is this possible?
I dont believe data bainding is the answer. I'd like to use Routed Events / Commands as they were designed just across the entire tree, not just within the source control's branch. Maybe it can't be done using routed events / commands, and data binding is the answer. I just dont know...
Any ideas?
The best mechanism is to refactor and separate the data view from the data model.
Create a data model that provides DependencyProperty properties (rather than standard C# properties) for each data point, but does not provide a UI. The values in the data model can affect each other when modified.
You can then bind each WPF element to the appropriate DependencyProperty from the data model. Modify the value in one element and all other elements are updated to reflect any data model changes in the bound properties.
If you want to transfer data between elements, Binding is the way to go. There are many tutorials and books about this on the net.
If you want to effect Style changes, then you can use DataTriggers, which also use Bindings.
There is no way to send events in the traditional sense between unrelated controls without wiring it up in the common root.

Resources