Calling UIElement Functions from View Model - c#

I am working on an MVVM C# Metro application that uses media components, particularly leveraging the play to capabilities.
Normally it seems that you would bind properties, however I need to make calls such as MediaElement.Play(source); and things such as that. The best solution I have come up with thus far is to fire an event from the view model that is handled by the code behind.
Is this in fact the best practice, or is there a more sophisticated approach?

There is an useful series of articles on MSDN that might help you to do this in more efficient way:
Multimedia Overview
Audio and Video How-to Topics
NOTE: These are still .Net 4 examples, but I bet that it will not require a lot efforts to run it with Windows 8 with all its enhancements.

I have tried doing a media player in WPF using MVVM way once, what I felt from my experience is that, it will be a real pain in doing it in the MVVM way. I would suggest write code behind if its less complex and faster than sticking to MVVM always, You can separate it as a user control later with some dependency properties if you want it to look cleaner.
Anyways, regarding the media playback what you could "also" do is keep a media player (Media Player) in your viewmodel and create a videobrush pointing to that mediaplayer and use it to show your video in the view. Rectangle or any other element for which you set the drawing brush can be used.
As your media player is the viewmodel, now you can play it, stop it, seek it etc
Something like this,
var player = new MediaPlayer();
var myVideo = new VideoDrawing { Rect = new Rect(0, 0, 1, 1), Player = player };
var dBrush = new DrawingBrush(myVideo);
// Use drawing brush to fill a rectangle
rectangle.Fill = dBrush;

Related

Controlling Sounds in audio in multiple forms

I want to play a playlist in the resources folder for a windows forms project I'm working on (wav or mp3). The application will be completely offline. (actually a game project)
What I want to do is this:
I need to be able to stop or convert a music that I created in one form to another sound file, depending on the situation.
In this case, I couldn't figure out how to write a code block. There are many examples that describe how we can pause and start the music on single form, but I have not come across an example that covers the whole project and can be intervened from different forms.
I'm not sure if I explained exactly what I wanted to ask, but I can give an example as follows. Let's say I created 3 forms.
1st form and 2nd form game menus.
In these menus, the same music should continue to play.
But when I reach the 3rd form, this music should be cut and replaced with in-game music.
What I want to ask is: How can I control the music I created in form 1, in form 2 or form 3?
The reason I don't use the soundplayer class is because I have to play multiple sounds at once.
i.e., somehow I need to make the music player "static" so that I can control it from all forms, but I couldn't find the way around it.
var importer = new RawSourceWaveStream(Properties.Resources.sound, new WaveFormat());
var soundFx = new WaveOut();
soundFx.Init(importer);
soundFx.Play();
For example, in this way, I start playing the music in the form1. I need to give the command to change this music in the form3, but somehow I cannot reach the "soundfx" object that I defined there because I cannot make this process static.
I think that your intuition is valid. It is probably not the best way, but I inffer that it is a way that you would manage to do.
Have a public static class, that holds a private (or public) instance of you sound player. Have public static methods of the different things that you want to do with the audio player.
Control that class from all forms.
Since this is your intuition. I am curious of what have you so far in this way?
Anyhow, I have a few questions.
When you say "convert" the music, what do you mean?
What do you mean that you couldnt find a way around it?
Can you add some code of how you are controlling the sounds? With some code, people will be able to better support you.
It is recommended that you use MediaPlayer. From your description, MediaPlayer can better meet your needs. Compared with SoundPlayer, MediaPlayer has the following characteristics:
Multiple sounds can be played at the same time (create multiple MediaPlayer objects);
You can adjust the volume (Volume property);
You can use Play, Pause, Stop and other methods to control;
You can set the IsMuted property to True to achieve mute;
You can use the Balance property to adjust the balance of the left and right speakers;
The speed of audio playback can be controlled through the SpeedRatio property;
The length of the audio can be obtained through the NaturalDuration property, and the current playback progress can be obtained through the Position property;
Seek can be performed through the Position property;
Use MediaPlayer to play audio files as follows:
MediaPlayer player = new MediaPlayer();
player.Open(new Uri("BLOW.WAV", UriKind.Relative));
player. Play();
A MediaPlayer object can only play one file at a time. And the file is played asynchronously, you can also call Close to release the file.
For details, please refer to https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.mediaplayer?view=windowsdesktop-7.0
When using it in VS, you need to perform the following steps first:
This way you can find MediaPlayer in the toolbar.
If you still have any questions please speak up.

WPF - C# - Creating and setting image coordinates in code - behind

I currently work on WPF application according to my AI interest.
I wrote a Uniform Cost Search algorithm (pathfinding) and want to present it in graphical way.
Path should be found and show on a graph which could be adjusted by user.
I'm quite new in WPF technology, I worked more with WinForms and now have a problem with creating and managing graphical elements.
In other words - I want to give opportunity to click on data grid and create your own node (sth like place on a map) which is represented by a picture, when you have a few nodes you can choose two of them and connect them to make a connection, finally you can select your start and end point and algorithm will show the shortest path (color the suitable connections).
That's it.
Image with interface
I started with adding a CreateNode method which gets click's coordinates and create a point with right X and Y. Now there is a problem with creating an image in that specific place.
I read some questions on Stack and tried to write something with Image and BitmapImge classes but still don't know how to place it in specific place.
I read about manipulating margins but aren't there any easier solutions?
Here's part of that image loading code:
public void CreateNode(Node n)
{
Point point = new Point(n.X, n.Y);
Image node = new Image();
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("point.png");
logo.CacheOption = BitmapCacheOption.OnLoad;
logo.EndInit();
node.Source = logo;
}
If someone has any ideas how to create these methods in case of graphics I will really aprreciate that.
Thanks in advance
Paweł
EDIT: I was said to create new topic for my code problem so here is that here
Moving my comment to an answer to provide a little more information.
With the positioning, I'd recommend watching this video on advanced XAML techniques. He uses a custom ItemsControl and Canvas to bind the longitude and latitude of delivery trucks to show as graphics on a map. I think some of his techniques could work in your situation (or give you further ideas). I've linked to the a timestamp at the start of the relevant section.
The source code for the relevant demo is available here. See Events - 2014 TechEd Europe - DEV-B311 XAML Techniques - Demo05
The main difference from what you're doing to the video is that he uses Paths where you want to use images. You'd need to change the DataTemplates in App.xaml.cs to use images.
The video assumes some knowledge of MVVM, so if that's new to you, it's probably worth checking out a tutorial. You can find some recommendations in the answers to this question. I'd also recommend one on Rachel Lim's Blog. I found her tutorials very useful.
The first linked tutorials on WPF look like they will be useful to you. In addition to the basics it includes using images in DataTemplates.

How would one make a custom gui in C#

I am interested in making a custom gui in C#, and I would like some advice as how to best go about that. The attached picture is generally what I would like to create - namely drawing text, boxes/backgrounds, pictures, lines, circles, and other gui elements (Like text input fields and the like).
I don't really know where to start, what I have been able to gleam from google searches is that GDI+ and using the paint event might be able to do what I am looking for - but I don't know if that is the way to go about making such a thing, or if it is the wrong tool for the job (aka it is slow/ineffective compared to something else).
//something along the lines of this:
private void Form1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Red, 5);
Rectangle myRectangle = new Rectangle(20, 20, 250, 200);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
Thank you for your time, and forgive me if I said anything incorrectly; I am having a hard time even describing to google what I am looking to do--- so your help is really appreciated!!!!
Is WPF an option for you? I would recommend it based on the screenshot you provided. This desktop GUI technology is much better suited than WinForms as your code sample suggests you are using.
Learn the basic of WPF and XAML via the link I provided.
Then learn about the Canvas panel
Then I suggest you learn about Templates
Well, this should get you going. If you have any specific questions I'm sure we' ll be happy to help here at SO.
Update Example of Canvas panel in Items control: https://dannyvanderkraan.wordpress.com/2015/02/12/wpf-listbox-with-arbitrary-positioning-and-custom-shaped-items/
You may use WPF or you can search for Windows Forms themes. You can do amazing custom gui by customising windows forms. If you are to create a new project I would suggest you WPF because it is easier to implement custom guy (especially transparency)

Drawing dynamic polygons in WPF

I am not sure if this is the right place to ask for such concept information advice, so I apologise if it's unrelated or off-topic to ask in Stack Overflow.
I want to develop an application in WPF which has the ability to draw polygons with the functionality of a regular control, they may change shape by adding, removing or moving vertices, change brushes all by run-time, from data-binding or perhaps direct manipulating from C# code (still not sure about that).
What I am trying to achieve is an application which draws a map and the shapes on it are the entities with the dynamic borders over the map (for instance say political borders). The polygons also have to be clickable controls with collision test (not just a bounding box, but exactly by the shape of the entity on the map). I can expect the shapes to be very detailed because of borders which found by rivers and mountains or other natural objects which not just a straight line of two vertices, so it's performance should be an important factor here because one polygon may contain hundreds of vertices).
What I've concluded that it is possible to achieve via WPF such an application. But my uncertainty is on the most efficient way to implement the map drawing, perhaps I should implement D3D hosting like SharpDX but I don't want it, it would make things even more complicated and difficult.
I prefer everything in this map to be functional as a regular WPF control with it's data-binding and stylising abilities. I've developed with WPF some several small test projects for months to learn the basics and its main concept. But now comes the main interest of mine to develop with WPF. I need some advice please, because drawing complicated and dynamic shapes is still not really clear to me to just go on and start develop it.
I would use WPF, indeed I would say WPF is perfect for this, though there will be considerable amount to learn. WPF uses DirectX so is preformant enough I imagine (provided you have the hardware).
You will need to become familiar with:
UserControl
DependencyProperties
Polygon
Canvas
However if you are not already familiar with Dependency Properties, they can be a headache to learn, so rather than creating your own UserControl with them, you can get away with a Canvas in your Window and build things programmatically or at design time in XAML.
As for actually drawing shapes; if you know ahead of time what the shapes will look like you can draw them ahead of time using tool like Blend (or by yourself in XAML - you will need to become familiar with the Path Markup Syntax) then you can use transforms such as a ScaleTransform to transform them at run-time, or if you want to build them at run-time you can do so programmatically adding points to a Polygon
e.g. from (Polygon)
//Add the Polygon Element
myPolygon = new Polygon();
myPolygon.Stroke = System.Windows.Media.Brushes.Black;
myPolygon.Fill = System.Windows.Media.Brushes.LightSeaGreen;
myPolygon.StrokeThickness = 2;
myPolygon.HorizontalAlignment = HorizontalAlignment.Left;
myPolygon.VerticalAlignment = VerticalAlignment.Center;
System.Windows.Point Point1 = new System.Windows.Point(1, 50);
System.Windows.Point Point2 = new System.Windows.Point(10,80);
System.Windows.Point Point3 = new System.Windows.Point(50,50);
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(Point1);
myPointCollection.Add(Point2);
myPointCollection.Add(Point3);
myPolygon.Points = myPointCollection;
myGrid.Children.Add(myPolygon);

If I have multiple forms in one application how can I smoothly transition between them?

If I want to smoothly switch between forms (i.e the sliding transition from
Microsoft PowerPoint), how can I do this? I am working with Visual Studios
C#.
If you're dealing with WPF, you can put them in a single Panel or Canvas, and apply/update continuously something to the "RenderTransform" property of the Panel/Canvas containing each. So,
Transform t = new TranslateTransform(0.0f, 0.0f);
panelA.RenderTransform = t;
panelB.RenderTransform = t;
Then with your favorite timing method, update t slightly each tick.
I'm sure there are more elegant ways (baked XAML animations, etc.) but I'm pretty shaky on giving advice with those, as I'm not quite sure on how to make them work myself. =)

Categories

Resources