Play sound when binding updates - wpf

hallo I want to play wav file in my WPF application when app detects disconnect from network. I am using MVVM pattern and PRISM. What I want to achieve is when my Viewmodel receives Event published by EventAggregator it sets some property to bool. I want to e able to listen to this property change from XAML and play sound based on its value

You might try to use System.Media Namespace SoundPlayer or MediaPlayer to play sounds based on Event Trigger in View Model
Eg:
readonly SoundPlayer _alertBeep = new SoundPlayer("FilePath");
private MediaPlayer _laserBeep = new MediaPlayer("FilePath");
SoundPlayer has option to only play / stop. But MediaPlayer is extended to have more controlling options.

You could make a converter that passes on the value as is and plays a sound with a MediaPlayer. That way, you could attach it to a specific binding instead of the view model.

Related

Animate a Helix Toolkit control drawn by a usercontrol

I am trying to achieve something very similar to this:
WPF with Helix toolkit, animate with code-behind?
However, my scenarios is slightly different. I am trying to animate a tube (curve) defined by a path (TubePath) which undergoes deformation as a function of time (animation) defined by a mathematical function (calculated numerically).
My design/plan is to use a usercontrol (containing the Helix Tube control) to draw each frame of the tube defined by a path. I plan to make the TubePath property in my usercontrol which is an oservablecollection a dependency property. I plan to control the animation from my ViewModel (or View) by binding the CurrentPath property of the ViewModel to the usercobtrol TubePath property. I plan to drive my ViewModel from INotifyPropertyChanged. I will a have List of Paths (PathList) stored in advance of starting the animation in my Model. At each (so called) time or animation step, I will copy the corresponding path from the PathList to the CurrentPath in the VieModel. I am hoping that change in the the CurrentPath collection in the ViewModel will activate the binding which will force the user control to update the tube drawn by the usercontrol.
These are my questions:
(1) I have read that not all changes to an ObservableCollection fires propertychanged events. Will overwriting or refereshing the whole CurrentPath collection in the ViewModel update the TubePath in the UserControl which will force redrawing of the tune? Do I have to do anything special to achieve this kind of binding.
(2) I am new to WPF and animations with WPF. My research indicated that I could do the animation from my ViewModel in several ways: using the Dispatcher.Invoke() like in the example given above, or I could use the RenderingEventManager.AddListener() (and RenderingEventManager.RemoveListener() to stop animation) provided by the Helix Toolkit like it is done in example here:
https://github.com/helix-toolkit/helix-toolkit/tree/develop/Source/Examples/WPF/ExampleBrowser/Examples/Wind
or I could loop using DispatcherTimer() as done here:
Binding on DependencyProperty of custom User Control not updating on change
Any suggestions as to the best method as well as my concept of driving animation from the ViewModel would be greatly appreciated.

WPF: Button Click on one ViewModel should exxecute a command on another viewmodel

i am kind of new to mvvm and i understand the basic concpects.
now i have a question:
i have two different viewmodels, which will be attached together on another wpf gui.
in one viewmodel, there is a button and a checkbox; ("left sided control")
now the "trick":
on the other viewmodel there is a checkbox, too. ("right sided control")
now: if the button was hit, then on the other viewmodel should be checked if the checkbox is set, too.
basicly i would do it with an event or a "signal", but the thing is, if the checkbox on the "right sided control" is checked, it needs a value from the "left sided".
the implemenation would be done by an event, and if so: how can i pass parameters??
as i am new to that mvvm i don't know exactly what i am really looking for and which solution would be "state of the art" and "mvvm"-style.
have a look at http://www.galasoft.ch/mvvm/, it has a Messenger class that i think it's exactly what you need
Firstly the UI interaction sounds a little complicated - it might be worth reviewing your UI interaction - could that be simplifed? Assuming not (i.e complexe UI need is real):
It sounds like left side view model (LVM) depends on a property of right side view model (RVM). So is it possible to setup that relationship in your view model properties i.e. Can LVM be setup to hold a ref to RVM and that the property that is bound to the check box itselft checks the dependant property on RVM? Then your command (bound on LVM) just has to check a proerty of LVM.
You need to use some Event Aggregator (for example from Prism library) for such stuff. Here is an c# pseudocode example of how to do it using Prism's Event Aggregator:
In your RVM:
_eventAggregator.GetEvent<LeftCBCheckedEvent>()
.Subscribe(SaveStateOfLeftCBLocally);
...
private void SaveStateOfLeftCBLocally(bool isLeftCBChecked)
{
_isLeftCBChecked = isLeftCBChecked;
}
In your LVM:
public bool IsLeftCBChecked {get; set;}
...
_eventAggregator.GetEvent<LeftCBCheckedEvent>().Publish(IsLeftCBChecked);
Event definition:
public class LeftCBCheckedEvent : CompositePresentationEvent<bool>{}
So when that button is pressed you'll already know the state of your left check box. And I strongly recommend to check Prism, it's a great library for composite applications, I think it can add a big value to your project.

WPF InotifyPropertyChanged and view models

So I think I'm doing something pretty basic. I know why this doesn't work, but it seems like there should be a straight foward way to make it work.
code:
private string fooImageRoot;
// ....
public BitmapImage FooImage
{
get
{
URI imageURI = new URI(Path.Combine(fooImageRoot, CurrentFooTypes.FooObject.FooImageName));
return imageURI;
}
}
So CurrentFOoTypes and FooObject also supports INotifyPropertyChanged.
So If I bind a TextBlock to CurrentFooTypes.FooObject.FooImageName, if either fooObject or FooImageName change the textblock updates. How can I subscribe my viewmodel object to recieve updates in a similiar fasion.
Correct me if I'm wrong. You want to be notified of changes to the properties FooImageName and FooObject, both owning objects use INotifyPropertyChanged to alert observers that these properties have changed.
Josh Smith had a nice article where he introduced a PropertyObserver object, which is used for just this scenario.
The MVVM Foundation includes this object as well as other helpful objects for MVVM development.
You can use the PropertyObserver, or custom code, to watch for changes in the properties you're interested in (in this case FooObject and FooImageName) and perform whatever actions you need to update the image URI based on those changes.

MVVM and window lists

I'm writing an app that lets users browse through data, and I want to use the FireFox UI style: allow the user to open as many windows as they want, each with as many tabs as they want. I also want to try to do this using the Model-View-ViewModel pattern as much as possible.
Opening a new tab should be easy enough to handle in MVVM. Make an ObservableCollection of TabViewModel, bind that collection to the ItemsSource of a TabControl, and then opening a new tab is theoretically as easy as adding a new TabViewModel to the collection.
Here's the question that interests me: Is there a way to do the same thing for opening a new window? I.e., databind an ObservableCollection of WindowViewModel to the ItemsSource of... the Application's Windows collection?... so that when I add a new WindowViewModel to the observable collection, a new window automatically opens? And then tie that into app startup, so that instead of setting StartupUri, I just add the first WindowViewModel to the collection?
Since I can't actually databind Application.Windows, what would be the best way for the ViewModel layer to:
Add a new WindowViewModel and have a new Window appear automatically;
Remove the WindowViewModel and have its Window automatically close.
Remove the WindowViewModel from the collection if the user closes the window.
I could write my own object that watches an INotifyCollectionChanged and opens/closes windows in response to collection events, but I'm not sure whether that's the best way -- and if it is, I'm not sure of the best way to hook it into the application. Anyone have thoughts on the best way to go about this?
The point of MVVM is, that the ViewModel doesn't have to concern itself (in detail) with how the View will react to changes in the ViewModel.
One possibility would be a simple tracking algorithm in the View listening to the CollectionChanged event in the ViewModel, creating and destroying Windows on the go:
Dictionary<WindowModel, WindowView> _cache = new;
void WindowModelListChangedHandler(sender, args) {
switch(args.Action) {
case Add:
_cache[args.NewItem] = new WindowView(args.NewItem);
_cache[args.NewItem].Show();
break;
case Remove:
// ...
}
}

How to further decouple this WPF example toward MVC, MVP, or MVVM?

I've decoupled events in this WPF application in the following way.
What is the best way to continue decoupling?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
The above code successfully decouples the view Shell from the model Customer:IPerson so that I can swap in e.g. a model Employee:IPerson etc. which handles "Processed" in its own way. That was the first goal.
But now:
how do I decouple the Processed method from talking specifically to a Button, so that it could also talk to a MenuItem or a ListView which fires the event in the view and so that it doesn't even have to be an element at all that calls it, e.g. a unit test class?
how do I alter other elements of the view other than the sender (Button), e.g. how would I alter the status bar in Shell? I see two ways:
I could either build a container which holds all views and inject the container in the Customer upon creation, then the customer can look in the container and manipulate the calling view anyway it wants (although I would have to somehow match the view that sent the event and the view in the container as the same one)
I could somehow send the whole view (Window object) to the Model with the eventargs when firing the event, although the Model would need some way of knowing (via interface) what kinds of regions were available to manipulate at runtime
How would you continue this application in the direction of a more decoupled design?
What pattern is this actually, e.g. MVC, MVP, MVVM? I only see a view (Shell) and a Model (Customer).
How would a Presenter fit in?
How would a ViewModel fit in?
How would a Controller fit in?
I suggest you to implement your event handling using commands instead of classic events.
Its very easy in WPF because the command pattern is already implemented, and you can tell all of your UI inputs (button, menu item...) that their command is [name of your command] and handle all of them in one place.
Cameron MacFarland did a good job here, but I can add a little.
When following M-V-VM, the tools in your box for decoupling are data binding, commands, attached behaviors and interfaces. Data binding should be self evident. You've already gotten a good description of commands, but I'd suggest you avoid RoutedCommand and stick with an ICommand implementation. Attached behaviors are attached DependencyProperty's that subscribe to events on the element they are attached to, and in this scenario would be used to relay event handling to the ViewModel. Interfaces give you the greatest flexibility, but you have to work out how to pass the interface to the ViewModel. The best way to learn all of this right now is to Google and to look at existing M-V-VM frameworks. Here's a list of frameworks:
Prism/Composite WPF (http://www.codeplex.com/CompositeWPF). This one comes from the Microsoft Patterns & Practices group. Lots of good stuff here, but one of the examples of the three things above that you can learn from here is how to use ICommand. Prism includes a DelegateCommand that implements ICommand and simplifies using commands from a ViewModel in M-V-VM.
Caliburn (http://www.codeplex.com/caliburn). Recently released, one of the key things you can learn from this one is how to use attached behaviors, which this library uses for it's "Actions".
Onyx (http://www.codeplex.com/wpfonyx). Disclaimer: I'm the author of this one. This one hasn't been released yet, though the current alpha source is available. This one provides a novel solution to the problem of how to provide interfaces to your ViewModel.
As Chen suggests, i'd look into the Command pattern: Routed commands
A working example from which i learned a lot can be found on Jaime Rodriquez his blog: Southridge
how do I decouple the Processed method from talking specifically to a Button
Commands. Put a command in the IPerson interface and call that command from the Shell's xaml.
how do I alter other elements of the view
Properties and Binding. If you have a property showing the state (processed/not processed) then you can use binding to display that property directly in the xaml.
How would you continue
I'd head more down the MVVM path by creating a ViewModel between the Shell and the IPerson. The ViewModel is designed to have 1) The properties needed for bindings, and 2) any Commands that need executing. The ViewModel is designed to provide the UI with what it needs from the Model.
What pattern is this
Currently? Nothing. I see only two objects, the View and the Model. You don't have a Presenter, Controller or ViewModel.
For WPF I prefer ViewModel. See this question for more info on MVVM.

Resources