Using Image Control in Silverlight (4) - silverlight

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.

Related

Reload a image using ReactiveUI and WPF

I am trying to change a image in the UI running with WPF on runtime by changing the source of the image. Unfortunately the image is not changing. I found examples of using a Bitmap image to change the Image source, but with ReactiveUI I am not able to change the UriSource for the BitmapImage.
XAML code:
<Image x:Name="button_image0" DockPanel.Dock="Top" Source="someimage.jpg" Stretch="Uniform" />
view code:
this.OneWayBind(ViewModel, vm => vm.button_image0, v => v.button_image0).DisposeWith(d);
Viewmodel code:
[Reactive] public string button_image0 { get; set; }
//button pressed
button_image0 = "newimage.jpg";
I checked that the source of the image is changing, but the image displayed is not. Does someone know how to solve this with reactiveUI or knows a way around?
Solution
If anyone is having the same problem, it's a syntax error of your code. When changing the source of an image using reactiveUI the image is reloaded. This question and answer confused me Reloading an image in wpf
When binding you should include the control property as part of the expression. For example
ContentControl.Content
SizableControl.Width
Image.Source
TextBlock.Text
So if you bind to the "Source" property on the Image on the view. You also appear to have your notation of v and vm the wrong way around which might be adding to the confusion. The viewmodel is the 2nd expression, the view is the 3rd.
this.OneWayBind(ViewModel, vm => vm.button_image0, vw => vw.button_image0.Source).DisposeWith(d);

How do you access to your image resources in MVVM WPF applications?

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.

How can I specify MediaElement.Source with non-relative uri?

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);

Display GIF in a WP7 application with Silverlight

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.

From and Image to an ImageSource

I have an image (embedded resource) that i can get access to and form an Image object from. I actually can get the Image object or the Stream of bits the represent the image. However I want to sue that image programaticly to be a background image.
So how do I set the ImageSource on the ImageBrush to an AcutalImage (PNG)?
I think the MSDN documentation says it all:
http://msdn.microsoft.com/en-us/library/system.windows.media.imagebrush.imagesource%28VS.95%29.aspx
You can either set the source as a URI in XAML, or use code behind to set it to an ImageSource object created from a stream or a Uri, e.g.
_imageBrush.ImageSource = new BitmapImage(new Uri("http://someurl.com/images/myimage.png"));
Cheers, Alex
EDIT: If your image is a ressource, you can use the ressource url syntax:
"/{AssemblyName};component/{RelativePath}"
For example:
<ImageBrush ImageSource="/MyApplication.Resources;component/Images/image1.png" />

Resources