We have some WPF modules which are hosted in a cpp unmanaged/managed application. This enviroment is causing troubles when specifying relative Uri's for media content. For example, I have no problem of doing something like this in a testapp:
<MediaElement Grid.Row="0" x:Name="player" Source="media\Getting started with.wmv" LoadedBehavior="Manual" UnloadedBehavior="Stop" Stretch="Fill"
MediaOpened="Element_MediaOpened" MediaEnded="Element_MediaEnded"/>
But, as mentioned, this does not work in production code.
If I try to use the pack schema like this:
Source="pack://application:,,,/media/Getting started with.wmv"
I get the exception:
Cannot navigate to application resource 'pack://application:,,,/media/Getting started with.wmw' by using a WebBrowser control. For URI navigation, the resource must be at the application�s site of origin. Use the pack://siteoforigin:,,,/ prefix to avoid hard-coding the URI.
If I try to use the 'siteoforigin' schema like this:
Source="pack://siteoforigin:,,,/media/Getting started with Olga 7.wmv"
I get another error:
Application identity is not set.
The media file is set up as "Content" and with "copy always".
How can I specify the MediaElement source using an absolute uri in a Wpf desktop application?
I found a solution (kinda). I am guessing that the relative url's can not be resolved because the main .exe is an cpp mfc application. So in order to create absolute uri's I did something like this:
player.Source = new Uri(CreateAbsolutePathTo("media/Getting started with.wmv"), UriKind.Absolute);
private static string CreateAbsolutePathTo(string mediaFile)
{
return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName, mediaFile);
}
I am binding to a viewmodel so this logic is wrapped into a property on the viewmodel and the source is databound in xaml.
Its working, but its not as pretty as I would like it to be.
Only you need to do this:
MediaElement bb = new MediaElement();
stage.Children.Add(bb);
bb.Source = new Uri("Recursos/MagicWandNoise.wav", UriKind.Relative);
Debug.WriteLine("URL:" + bb.Source);
bb.LoadedBehavior = MediaState.Manual;
bb.Play();
And then add the Binary Resources in your folder debug, check this link
Remember the media element to work fine, you need to add in a Visual Three
Canvas.Children.Add(bb);
Related
Using IronPython and WPF in VS2017:
I have added an icon located in my code source directory to the XAML Window tag. I've also included the file in the project in the solution explorer. If I use the full file C: drive file path, it works. But, I need to use a relative path because it will be run on other computers.
If I try Icon="../xxx.ico" the file isn't found (squiggly line, "Cannot find...).
If I try Icon="xxx.ico" the file IS found while editing, however at run-time I get an exception
Exception: Failed to create a 'Icon' from the text 'xxx.ico'.
It seems that the Python interpreter cannot locate it.
What do I need to do so that it is found at run-time?
Ran into this same issue myself and have found a solution, albeit a little late!
It does indeed seem that IronPython interprets the field as text unless it determines a valid uri is present.
We can get around this via code, a bit of reading into c# and how it handles icons was needed here;
Dynamically setting our path and file
location at runtime.
Create a BitmapImage
after casting our file location as a c# Uri
Update our xaml to give our window an x:Name=""
Set our window.Icon to the BitmapImage we defined earlier
XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="en-AU"
x:Name="window">
</Window>
Code behind
import os
import clr
clr.AddReference('System')
from System import Uri
from System.Windows.Media.Imaging import BitmapImage
class Application(Window):
def __init__(self):
## Set our icon file path dynamically based off working directory ##
icon = os.path.join(os.getcwd(), 'app-logo.ico')
## Define BitmapImage from Uri(filepath) ##
self.icon = BitmapImage(Uri(icon))
## Load our wpf component, defined under self.ui to allow easy access ##
self.ui = wpf.LoadComponent(self, 'application.xaml')
## Set our XAML x:Name="window"'s Icon field to our BitmapImage
self.ui.window.Icon = self.icon
Thats it! Our Icon is now set and working as intended.
Taskbar:
Application Icon:
I've added a XAML file to a Windows Phone 8 project. Its build action is "Page". I want to load the XAML as a text string (to feed into XamlReader.Load()). How can I accomplish this?
It's not available as a separate file in the XAP package; it's probably somewhere in the DLL.
When set to Page, the compiler will compile the XAML into BAML and add the BAML file as a resource to the assembly.
If you wish to get the original XAML back out from the BAML resource at runtime, then you will need to deserialize the BAML, and then serialize your object to XAML.
You can have a look at the Baml2006Reader, or a better option would be to use Application.LoadComponent which is what the InitializeComponent method uses internally. InitializeComponent is called by the partially generated class for your XAML code behind.
var uri = new Uri("/MyAppName;component/MyXaml.xaml", //Note extension: XAML, not BAML
UriKind.Relative);
Page rootObject = new Page(); //Assuming XAML root element is Page - it could be anything
Application.LoadComponent(rootObject, uri);
(assuming the root element of your XAML file is a Page).
You can then serialize the Page to a XAML string using the XamlWriter:
string xaml = XamlWriter.Save(rootObject);
Note that this is the XamlWriter in the System.Windows.Markup namespace, not System.Xaml. If your XAML has WPF types, then you should use this XamlWriter to avoid errors.
I have been integrating image resources to my WPF assemblies for quite a time, but I never really found a really pretty way of binding them in my MVVM applications.
So I was wondering if some you, stackoverflow users, could share their own practice when it comes to assembly ressources:
How do you reference them in C#/VB and XAML?
When exposing them from code, what type do you expose? (BitmapImage, Uri, string, ...)
Do you prefer referencing them from the view or binding them through view-model?
Do you use a specific assembly to store them? How do you organize them?
Thanks for your help ;-)
This is what I do...
Images are kept in some folder such as Images in project's root folder. You can keep them in any assembly.
Individual image has Build Action property set to Resource type.
The ViewModel holds image name in string (say property MyImageName) and I convert it as a relative path when bound to the Source of Image object in XAML...
public class ImagePathConverter
{
public void Convert(...)
{
return "pack://application:,,,/MyApplicationName;component/Images/" + value.ToString();
}
}
where MyApplicationName is the short assembly's name that is having the Images folder under it.
In XAML, assuming the view model instance is bound to the data context of the entire view and / or atleast to the image's data contect ....
<Image Source="{Binding Path=MyImageName, Converter={StaticResource ImagePathConverter}}" />
But then thats one of the typical ways to refer images in a WPF project via MVVM. Other ways include an Image's binary stream loaded (from resx or Content type images or from binary database). In such case your converter will convert it into a BitMapImageSource.
I'm trying to use the Image control is a very basic way, like here:
http://www.silverlightshow.net/items/Using-the-Image-control-in-Silverlight-2-Beta-1.aspx
So I'm ending up with XAML like this:
<Image x:Name="imgSmall" Stretch="Fill" Source="../Img/Small/105.jpg" Margin="10,0,0,0"></Image>
Which isn't working. The Image is blank, and in the designer the URI is underlined with a message of "...is not part of the project or its build action is not set to 'Resource"
If I change the source to a property on my ViewModel, set like this:
new Uri(App.Current.Host.Source, "../Img/Small/105.jpg");
Then it works fine. I'd much prefer to use the simpler syntax and get the image directly. Is this possible?
(The images are one level up from ClientBin)
Setting all of my web sites images to build=Resource is not possible.
Thanks!
You have to create a converter that takes the relative image path and adds the "absolute" part. You can pass the relative Uri as binding value or as converterParameter.
class ImageConverter : IValueConverter
{
// method convert()
return new BitmapImage(new Uri(App.Current.Host.Source, ((string)parameter));
//...
}
It id doesn't work because image is not added to your project.
Add image to project and in then you can set source from xaml.
I would like to display gif in my WP7 application.
Is there some way to achieve this ?
I've tryed this one http://imagetools.codeplex.com/ but can't make it working with WP7.
Thanks in advance for any help
In fact,
it's working, but it lacks some documentation.
After some troubles, here's how to use it :
reference ImageTools
reference ImageTools.Controls
reference ImageTools.IO.Gif
Add namespace in xaml :
xmlns:imagetools="clr-namespace:ImageTools.Controls;assembly=ImageTools.Controls"
And resources :
<phone:PhoneApplicationPage.Resources>
<imagetools:ImageConverter x:Key="ImageConverter" />
</phone:PhoneApplicationPage.Resources>
Then use the control with the converter :
<imagetools:AnimatedImage Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}" />
Your ImageSource should be an Uri, for example :
ImageSource = new Uri("http://mysite/my.gif", UriKind.Absolute);
Don't forget to add decoded :
ImageTools.IO.Decoders.AddDecoder<GifDecoder>();
Check out Jamie Rodriguez's post here on using GIFs with WP7. He uses the ImageTools project from CodePlex.
http://blogs.msdn.com/b/jaimer/archive/2010/11/23/working-with-gif-images-in-windows-phone.aspx
I struggled to get the accepted answer working. The following solution worked for me to display a static gif.
public ImageResponse(string imageUrl)
{
InitializeComponent();
ImageTools.IO.Decoders.AddDecoder<GifDecoder>();
var imageResponse = new ExtendedImage();
imageResponse.UriSource = new Uri(imageUrl);
imageResponse.LoadingCompleted += this.ImageResponseLoadingCompleted;
}
private void ImageResponseLoadingCompleted(object sender, EventArgs e)
{
var imageResponse = (ExtendedImage)sender;
Classes.Util.UiThread.Invoke(() =>
{
this.ImageResponse.Source = imageResponse.ToBitmap();
});
}
Classes.Util.UiThread is a helper class I use to call the UI Thread
this.ImageResponse is a standard image control
Is it an animated GIF? If not, I would try converting the GIF to another supported file format before using it in your app.
WP7 Silverlight supports JPG/PNG.
As per http://msdn.microsoft.com/en-us/library/ff462087(VS.92).aspx the Silverlight image control does not support GIF files.
By using ImageTools you are converting the GIF file to something else on the fly on the device. If you are using gif files that you have control of (i.e. You are bundling them in the XAP or they are coming from your webserver.) you should use converted versions of these files.
This will mean that the app has to do less.
The knock on effect is that:
1. You will have to write less code.
2. The app will have to do less work and so will perform slightly better.
Of course, this doesn't cover animated GIFs. For these you'll need to use a different approach.