Using Bitmap Class in XAML [duplicate] - wpf

I have two .png files added to my resources which I need to access their Uri when doing binding.
My xaml code is as followed:
<Grid>
<Image>
<Image.Source>
<BitmapImage DecodePixelWidth="10" UriSource="{Binding Path=ImagePath}"/>
</Image.Source>
</Image>
</Grid>
and the binding code using ImagePath is:
ImagePath = resultInBinary.StartsWith("1") ? Properties.Resources.LedGreen : Properties.Resources.ledRed;
However
Properties.Resources.LedGreen
returns a Bitmap instead of String containing the Uri of that particular image.
I just want to know how to extract that value without a need to address a path of the image in the directory that it's stored. (Which honestly I am not sure is a right thing to do as I couldn't find any similar situation on the net).
Please let me know if there is even a preferred method to the one I am trying to use if available.

In a WPF application you would usually not store images in Properties/Resources.resx and access them by means of the Properties.Resources class.
Instead you just add the image files to your Visual Studio project as regular files, perhaps in a folder named "Images" or the like. Then you would set their Build Action to Resource, which is done in the Properties window. You get there e.g. by right-clicking the image file and select the Properties menu item. Note that the default value of the Build Action should be Resource for image files anyways.
In order to access these image resources from code you would then use a Pack URI. With the above folder name "Images" and an image file named "LedGreen.png", creating such an URI would look like this:
var uri = new Uri("pack://application:,,,/Images/LedGreen.png");
So you could perhaps declare your property to be of type Uri:
public Uri ImageUri { get; set; } // omitted INotifyPropertyChanged implementation
and set it like this:
ImageUri = resultInBinary.StartsWith("1")
? new Uri("pack://application:,,,/Images/LedGreen.png")
: new Uri("pack://application:,,,/Images/LedRed.png");
Finally your XAML should look like shown below, which relies on built-in type conversion from Uri to ImageSource:
<Grid>
<Image Width="10" Source="{Binding Path=ImageUri}" />
</Grid>

Declare the Properties.Resources.LedGreen property as ImageSource and set it to Uri location rather than the Bitmap object.
Or if you insist of storing it as a bitmap you can get the source by returning Properties.Resources.LedGreen.ImageSource which will be of type ImageSource.
I would prefer the first approach.

Related

Images bound to images added to resx files using XAML

My WPF application includes a resource file MyResources.resx, containing several strings and images. Because the application will need to be localized, all my references to globalized resources must be made via named properties of the auto-generated MyResources class. The following code works well for string resources:
<Button Content="{x:Static local:Properties.MyResources.ButtonText}" />
However the same does not work for images. Assuming I have an image eflag.bmp added to the resources as a resource named Flag, I would like to be able to do something like this:
<Image Source="{x:Static local:Properties.MyResources.Flag}" />
Please note that the following alternative approach:
<Image Source="/MyNamespace;component/Resources/eflag.bmp" />
cannot be used in this case because it will not be able to handle localization. The problem can be solved using code behind but I am looking for a XAML based solution.
Turn your x:Static into a Binding.Source and add a Converter which does Bitmap to ImageSource.
Source="{Binding Source={x:Static local:Properties.MyResources.Flag},
Converter={StaticResource BitmapToImageSourceConverter}}"
Alternatively you can make the converter a custom markup extension which takes a Bitmap and returns the ImageSource in ProvideValue.
Source="{me:BitmapToImageSource {x:Static local:Properties.MyResources.Flag}}"

bound picture to control in WPF without using converter

i'm having a custom object with Picture as a string (file name only)
and i want to display.
the problem is that the image is stored in "images" directory of the project so the full path is now "images/{image name}"
how can i bind it correctly ?
i can do it easily with converter i guess, but is there any way to avoid it like:
<Image Source="{Binding Path=FullPath+"/"+Picture}"> ?
You could bind to an aggregated property in your ViewModel and then put whatever path you like into that. That way the ViewModel becomes the 'converter'.

binding an image source in XAML

I am trying to bind an image source to my XAML through c#
this works
<Image Source="images/man.jpg"></Image>
this does not work
<Image Source="images/{Binding imagesource}"></Image>
where imagesource is a string variable in the c# file of this xaml and is being set equal to "man.jpg"
here is a way how to do it in XAML:
add this to the namespace:
xmlns:System="clr-namespace:System;assembly=mscorlib"
then add your images paths
<System:String x:Key="ImageRefresh">/Theme;component/Images/icon_refresh.png</System:String>
<System:String x:Key="ImageSearch">/Theme;component/Images/icon_search.png</System:String>
This is how you use it
<Image Height="16" Source="{StaticResource ImageSearch}" Stretch="Uniform" Width="16"/>
This works ok, but if you load your xaml style in Blend it will go bogus..
An object of type "System.String" cannot be applied to a property that expects the type "System.Windows.Media.ImageSource".
I haven't figured out yet, how to replace System:String with that Media.ImageSource... but hey.. it works for me in Visual Studio.
You can't stick a binding mid-way through the value like that. It's either a binding, or it's not. Assuming imagesource is publicly accessible via your DataContext, you could do this:
<Image Source="{Binding imagesource}"/>
However, if it's been set to "man.jpg" then it won't find the image. Either set imagesource to the full path ("images/man.jpg") or use a converter:
<Image Source="{Binding imagesource, Converter={StaticResource RelativePathConverter}}"/>
The converter would prepend "images/" onto its value. However, it may be necessary for the converter to return an ImageSource rather than a string.
Images have bitten me in the past. There is a certain lookup order involved.
When you use "image/man.jpg" it could refer to a file inside your silverlight xap, or relative to the location of XAP file. For example, it could be in YourProject.Web/ClientBin/image/man.jpg.
You should troubleshoot by using full URLs first and find out if this works.
imagesource needs to be an actual Image object, not a string.
Here is a method that will create a new Image object given a path:
public BitmapImage Load(string path)
{
var uri = new Uri(path);
return new BitmapImage(uri);
}

get absolute file path from image in WPF

I have something like this in my xaml:
<Grid>
<Image Name="image" Source="../../Images/DefaultImage.png" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Image>
</Grid>
How can I get (using my code-behind C# code) the absolute path of the image source?
The method which works for me every time is this simple line
(YourImage.Source as BitmapImage).UriSource
In addition you can work on AbsolutePath or AbsoluteUri of UriSource returned according to your need.
When converted from a Uri string or filename, the ImageConverter creates a BitmapDecoder and extracts its first Frame. Getting the Uri should be possible with:
((BitmapFrame)image.Source).Decoder.ToString()
Note that this will generally return an absolute Uri rather than the original Uri found in the XAML. If you need the exact original Uri from the XAML, it is found in the _uri field of the BitmapDecoder but you'll need reflection and elevated code permissions to get to it, plus your code may not work in future NET Framework versions.
You could try this:
string path = ((BitmapImage)image.Source).UriSource.AbsolutePath;

How to get base uri of referencing XAML in a custom control

I have an custom control, which has an Image element with its Source property exposed to user, like this:
<ControlTemplate>
<Image x:Name="PART_Image" Source="{Binding ImageUri, RelativeSource={RelativeSource TemplatedParent}}"/>
</ControlTemplate>
where ImageUri is an property in the control class, like this:
public Uri ImageUri { get; set; }
This custom control is in an assembly customcontrol.dll, I can reference and use this control in an .exe with no problem, like this:
<cc:MyControl ImageUri="/Resources/Image.png" />
where Image.png is a resource of the .exe project.
But if I reference and use this control in an dll assembly, there is a problem, I have to use a absolute "pack://..." uri to reference an image in the calling dll, if I use an relative uri like "Resources/Image.png", the resource cant be loaded, it turns out, when this uri is applied on the Image element, it resolves the relative uri from customcontrol.dll, not the calling dll assembly, so I want to do this:
public Uri ImageUri {
get { ...... }
set {
if (!value.IsAbsolute) {
// Get the assembly name of parent xaml file or code
// and construct a "pack://" uri from the assembly name
// and value.OriginalString, but how ??????
}
}
}
How can I get the assembly of the XAML code that uses my custom control?
If the control is used in code maybe I can use GetCallingAssembly in my methods, but XAML stuff is called from PresontationCore.dll, how can I find out the XAML assembly???
OK I have found a solution myself. I should implement IUriContext interface,
which has only one property: Uri BaseUri, this is exactly what I want.

Resources