I have a class library written in C# for Windows 8 with a custom control and a folder called Images with bunch of images in it. In control template I have an image
<ControlTemplate TargetType="local:MyCustomControl">
<Grid Background="Transparent">
<Image x:Name="MyImage"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Stretch="Fill" />
...
</Grid>
</ControlTemplate>
I want to set in this control's code-behind one of that images (which are inside this class library) as a source for this image.
What I have already tried:
Absolute uri using FrameworkElement.BaseUri with both Do Not Copy and Copy Always property values of images:
this.MyImage.Source = new BitmapImage(new Uri(this.BaseUri, imagePath));
Relative uri with both Do Not Copy and Copy Always property values of images:
this.MyImage.Source = new BitmapImage(new Uri(imagePath, UriKind.Relative));
ms-resource uri scheme.
How can I achieve it?
Ok, that escalated quickly. :) Maybe, will be useful for others.
The solution is to use assembly name of the library in the path:
var assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name;
this.MyImage.Source = new BitmapImage(new Uri(this.BaseUri, assemblyName + imagePath));
Related
I am attempting to set the image source in an effort to ultimately pull corporate standard images from what will be a DLL reference.
For testing and to ensure the proper syntax of the Uri, the image was loaded locally to a test project and the source was hard coded in the XAML.
<Image Name="imgTest" Source="pack://application:,,,/test2;component/Dictionaries/bricks.png"/>
The hardcoded value of imgTest.Source was viewed in debug mode and reads:
imgTest.Source = "pack://application:,,,/test2;component/Dictionaries/bricks.png"
Next, the source for the image was set in code.
BitmapImage imageUri = new BitmapImage();
imageUri.BeginInit();
var imageSource = new Uri(#"pack://application:,,,/" + Assembly.GetExecutingAssembly().GetName().Name + ";component/" + "Dictionaries/bricks.png", UriKind.Absolute);
imageUri.UriSource = imageSource;
imageUri.EndInit();
imgCopy.Source = imageUri;
The softcoded value of imgTest.Source was viewed in debug mode and reads:
imgTest.Source = "pack://application:,,,/test2;component/Dictionaries/bricks.png"
Both the hard coded and soft coded values are identical however the image does not render with the soft coded configuration.
Updates of the 'Build Action' property for the image have been attempted with Embedded Resource, Content, and Resource in combination with each of the three options available for the 'Copy to Output Directory' property.
Any wisdom on this issue is greatly appreciated.
Edit # 1
A side-by-side comparison where I copied the Source property to the soft coded image yields no image being displayed while the hard coded image does yet debug shows identical Source values. XAML and C# code shown.
<Image Name="imgCopy_Soft" />
<Image Name="imgCopy_Hard" Source="Dictionaries/bricks.png" />
imgCopy_Soft.Source = imgCopy_Hard.Source;
Edit # 2 Here is the full XAML
<UserControl x:Class="test2.ucConfigurator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:test2"
mc:Ignorable="d" Height="439.5" Width="400">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<Image Name="imgCopy_Soft" Grid.Column="0" />
<Image Name="imgCopy_Hard" Grid.Column="1" Source="pack://application:,,,/test2;component/Dictionaries/bricks.png" />
</Grid>
</Grid>
</UserControl>
And the code behind it:
namespace test2
{
public partial class ucConfigurator : UserControl
{
public ucConfigurator()
{
InitializeComponent();
}
public void Initialize()
{
BitmapImage imageUri = new BitmapImage();
imageUri.BeginInit();
var imageSource = new Uri(#"pack://application:,,,/" + Assembly.GetExecutingAssembly().GetName().Name + ";component/" + "Dictionaries/bricks.png", UriKind.Absolute);
imageUri.UriSource = imageSource;
imageUri.EndInit();
imgCopy_Soft.Source = imageUri;
imgCopy_Soft.Source = imgCopy_Hard.Source;
}
}
}
First, the DLL needs to be added as a References in Visual Studio:
I created a library project inside the same solution and named it _ImageLibrary. I then checked the box for it so it will be added to my project like so:
Inside the DLL, I set the image to this:
I have an image called awesome-cat.jpg. It is inside of a project directory called Resources.
I can then access it like so:
<Image Source="pack://application:,,,/ImageLibrary;component/Resources/awesome-cat.jpg"/>
REMEMBER!!! The portion of the XAML above shows the ASSEMBLY NAME and NOT the project name!!!! My assembly is ImageLibrary.dll.
Now if you HAVE the DLL as a loose file, just add it to your project and then reference that in References using the Browse feature.
It should be noted, this will only work if the DLL is shipped along side your exe. If you want to embed the DLL, then that is a whole different ball game and I can show you how to do that if you ask a separate question for it.
I'm developing a small WPF application and I'm trying to change the background of a grid to an image the user chooses (stored somewhere on the computer on a different location from the app). Is it possible without having the images included on the project and marked as a Resource? How?
Assuming you Grid name is grid, then xaml would be:
<Grid Name="grid">
...
</Grid>
then to set an image programatically to grid, you should use the following code snippet:
string imgPath=#"E:\anImage.jpg";
grid.Background= new ImageBrush { ImageSource = new BitmapImage(new Uri(imgPath,
UriKind.RelativeOrAbsolute)) };
you just need to set the image's source URI to the image location
<Image Source="<<URI of image>>"/>
<ImageBrush ImageSource="<<URI of image>>"/>
or you can do the same via binding to allow it to be customised
<Image Source="{Binding Data}"/>
in this example Data is a byte[] stored in the model, but could be anything that converts to an image source
This works for me :
1) Add image in solution (Add => Existing Item)
2)<Grid>
<Grid.Background>
<ImageBrush ImageSource="/App;component/Chrysanthemum.jpg">
</ImageBrush>
</Grid.Background>
</Grid>
I am currently trying to get an image to show in design time in my Xaml with the code below:
Xaml:
<Canvas Grid.ColumnSpan="2" Margin="0,0,0,0">
<Image Canvas.ZIndex="1" Source="{Binding Coupon.OverlayImage}" Margin="0,-21,-76,108" Stretch="Fill" x:Name="PrintImageContextMenu" />
</Canvas>
C# Design Time:
Coupon.OverlayImage = Image.FromFile(#"C:\Temp\Images\TestImage.png");
Original Property of OverlayImage in VB (Legacy Code):
private _overlayImage as Image
Public Property OverlayImage As Image
Get
Return _overlayImage
End Get
Set
_overlayImage = value
NotifyPropertyChanged("OverlayImage")
End Set
End Property
Upon first view I cannot see anything wrong with but it does not show, even at runtime. Any ideas would be appreciated.
You can use Image Fallback value to set the default image.Here is a simple example.
<Window.Resources>
<BitmapImage x:Key="ImageSource" UriSource="C:\Temp\Images\TestImage.png"/>
</Window.Resources>
<Grid>
<Image
HorizontalAlignment="Left"
Source="{Binding SourceImage,FallbackValue={StaticResource ImageSource}}"/>
</Grid>
Everywhere you use the Image class, I think you use the System.Drawing.Image because the WPF Image control does not have a FromFile() method . You cannot use it as a source for the WPF Image Control. You must instead try using an IValueConverter to convert the Image to a BitmapSource/ImageSource.
Try this,
var uri = new Uri(Coupon.OverlayImage);
var bitmap = new BitmapImage(uri);
ImageName.Source = bitmap;
is there a nice way to do the following. Get a WPF button and a Windows.Forms.ImageList and use them together. Here is the code:
<Button Name="SOMETHING" Content="Button" Height="23" VerticalAlignment="Top" Width="75"/>
System.Windows.Forms.ImageList imgList = new System.Windows.Forms.ImageList();
string str_directory = System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
this.imgList.Images.Add(System.Drawing.Image.FromFile(str_directory + "\\Resources\\AboutImage.png"));
WPFbutton.Background = imgList.Images[0];
I am tyring to get the Windows.Forms ImageList and use it on a WPF button. Is there a nice way to fix it?
There is no need for an ImageList. Just do it as shown in the code below, which assumes that the path "Resources\AboutImage.png" is relative to the application's current working directory.
Apparently you've called Path.GetDirectoryName two times to cut off the "bin\Debug\" or "bin\Release\" part of the path and thus access the image file directly from the Visual Studio project structure. This will not work when the application is deployed somewhere else. Instead, set the Build Action of the image file to Content, and Copy to Output Directory to Copy always or Copy if newer.
var path = Path.Combine(Directory.GetCurrentDirectory(), "Resources", "AboutImage.png");
var bitmap = new BitmapImage(new Uri(path));
WPFbutton.Background = new ImageBrush(bitmap);
However, a far better approach would be to load an image resource directly. Set the Build Action to Resource and load the image by a WPF Pack URI:
var bitmap = new BitmapImage(
new Uri("pack://application:,,,/Resources/AboutImage.png"));
WPFbutton.Background = new ImageBrush(bitmap);
Besides that, you would usually set the Background in XAML, like:
<Button ...>
<Button.Background>
<ImageBrush ImageSource="/Resources/AboutImage.png"/>
</Button.Background>
</Button>
In a legacy project there are absolute path to the images,
for example:
C:/projects/LegacyProject/Project/Client/UserInterface/Images/arrow.png
Now I want to use relative path, so that every developer can use that
project, no matter where he has his copy of the sourcecode.
Is there an easy way to find out the (Resource) relative path?
How can I use it then?
At the moment I have for example:
<Image Source="C:/projects/LegacyProject/Project/Client/UserInterface/Images/arrow.png" Stretch="Fill" />
What I want is something like:
<Image Source="arrow.png" Stretch="Fill" />
Tried around with
<Image Source="pack:,,, arrow.png" Stretch="Fill" />
<Image Source="/WPF1;arrow.png"></Image>
and similar things
Put the image files into a folder (named let's say Images) in your Visual Studio project and set their build action to Resource.
Now you can simply use them in XAML like this:
<Image Source="Images/arrow.png" ... />
In code-behind you would have to write
var uri = new Uri("pack://application:,,,/Images/arrow.png");
image.Source = new BitmapImage(uri);
Add image using Source property of the Image control by clicking
then the path will be something like this:
/[project name];component/[folder name: e.g. Images]/[file name]