How to set relative uri from xaml in wpf? - c#

So I am wondering where the relative uri should be set relative to. I had assumed it was the main project.
I have the image stored under a folder images. The images folder is directly under the project DaedalusGraphViewer under the solution which also has the same name (DaedalusGraphViewer).
I had assumed that the relative uri was relative to the project, but I don't seem to be having any luck. Alternative ideas such as doing it from code behind are also welcome. I have done it from code behind before so I can probably figure that out since I will be able to debug it better there, but I would prefer to just do it in xaml.
I am using
<ResourceDictionary Source="DaedalusGraphViewer/ResourceDictionaries/GraphViewerBrushes.xaml" />
to do the same thing elsewhere, so I don't see what I'm doing wrong.
<Button
Height="50"
VerticalAlignment="Top"
>
<Image Width="50" Height="50" Source="Images/zoominbutton.bmp" Stretch="Fill"/>
</Button>
edit: still no luck, not sure what I'm doing wrong.
i've revised the code to use a much smaller test case.
ideally i would like to be able to set the image path from xaml, but for now i'm trying code behind just to see if I can figure out anything that will make it work.
<Window
x:Class="TestApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
Loaded="Window_Loaded"
>
<Canvas x:Name="MainCanvas">
<!--<Image x:Name="ImageSource2" Width="50" Height="50" Source="/DaedalusGraphViewer;component/images.jpg" Stretch="Fill"/>-->
<!--<Image x:Name="imagetest" Stretch="Fill" Width="50">
<Image.Source>
<BitmapImage
DecodePixelWidth="200"
UriSource="/Images/images.jpg"/>
</Image.Source>
</Image>-->
<!--<Image Width="50" Source="../../Images/images.jpg" Stretch="Fill"/>-->
</Canvas>
</Window>
namespace TestApp
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Image i1 = new Image();
Uri relativeuri = new Uri("/DaedalusGraphViewer;component/images.jpg", UriKind.Relative);
BitmapImage bmi = new BitmapImage(relativeuri);
i1.Source = bmi;
MainCanvas.Children.Add(i1);
}
}
}
My goal for now is just to display an image on the main canvas. When do I need to use an absolute uri and when can I use a relative Uri. I have read lots of examples of xaml using relative uris so I thought that would be possible.

Replace YOURAPPNAME
<Image Width="50" Height="50" Source="/YOURAPPNAME;component/Images/zoominbutton.bmp" Stretch="Fill"/>

I got it to work using "pack://application:,,,/images.jpg" as the source. However, I'm still confused as to why I can't get a relative pack uri to work like this:
http://msdn.microsoft.com/en-us/library/aa970069.aspx
I thought I could just use a source = "/images.jpg"
I read elsewhere that there is a default string to uri converter that converts the relative uri to an absolute uri based on the assembly being built.
anyway if anyone knows how to get the relative pack uri to work or why it doesn't work, please let me know.
I also got ebattulga's answer to work, so I'm selecting it as the right answer. However, I would like to understand a bit better why the relative pack uri from the pack uri site doesn't work.
ps - It doesn't appear to work with the image set to content. I got it working with the image build type set to resource
ps2- I haven't been able to get the same code to work with .bmp extension images. Not sure what is going on.

Related

WPF image not rendering after setting source

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.

Why is an image resource in a class library not loaded?

I have strange problem, which I don't know how to find - I looked for similair posts here, but failed.
Problem is that I have custom control in WPF and, obviously, I want to reuse it in multiple projects.
I have image background in that control with label over it (assured with Panel.ZIndex).
In one project it is showing correctly, but in another just Label is showing, image for some reason does no display.
What could problem be? I am loosing my mind over this...
Below code of a control:
<UserControl x:Class="SampleControls.LabelWithBoxBackground"
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:SampleControls"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="400" x:Name="labelWithBoxBackground">
<Grid>
<Image Source="pack://application:,,,/Images/boxImage.png" Stretch="Fill" Panel.ZIndex="1"/>
<TextBlock Background="White" Text="{Binding ElementName=labelWithBoxBackground, Path=Text}" Margin="0,20,0,0" Panel.ZIndex="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontFamily="Calibri"/>
</Grid>
</UserControl>
Code behind:
public partial class LabelWithBoxBackground : UserControl
{
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(LabelWithBoxBackground), new FrameworkPropertyMetadata(string.Empty));
public string Text
{
get { return GetValue(TextProperty).ToString(); }
set { SetValue(TextProperty, value); }
}
public LabelWithBoxBackground()
{
InitializeComponent();
}
}
Use a full Resource File Pack URI, including the assembly name (not the namespace) of your UserControl library, as shown below.
Otherwise WPF resolves the Pack URI with the name of the "local" assembly, which may be that of the main application.
Source="pack://application:,,,/SampleControls;component/Images/boxImage.png"
Also make sure that the Build Action of the image file is set to Resource.
As a note, setting Panel.ZIndex is pointless here. The elements are stacked by default in the order they are declared in XAML, so the TextBlock is always on top of the Image, even without setting ZIndex.

Image.FromFile not loading into design time view c#.net

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;

How can I change the StaticResource used in a VisualBrush from code behind in response to the correct user input?

I have a rectangle with the fill set to an icon from the icon set that comes with MahApps.Metro
Here's the code
<Rectangle x:Name="urlIcon" HorizontalAlignment="Left" Height="26" Margin="448,48,0,0" VerticalAlignment="Top" Width="28">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource appbar_warning}" />
</Rectangle.Fill>
</Rectangle>
In the XAML design I have a URL box that gets user input web address. In the code behind, I check if the web address is reachable, if it is, then I'd like to change the Static Resource to another icon "appbar_check"
Here's the event method for the URL box. urlExists is another method that does the checking of the url.
private void urlBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
String url = ((TextBox)sender).Text;
if (urlExists(url))
{
//change icon
}
}
You can access the resource to fill the rectangle as below
urlIcon.Fill = new VisualBrush() { Visual = (Visual)Resources["appbar_check"] };
also since your resources are UIElements then inorder to use them multiple places you need to set <Canvas x:Shared="false" > on the canvas resource in order to return a new resource everytime you ask. Otherwise it will give an error that the visual is already child of some other control.
As I am on learning curve of WPF I am not sure of the syntax.
But you can try something like this.
urlIcon.Fill(new VisualBrush(...))
May this help you or give you an idea
For that kind of use, you might better use DynamicResource.

Image binding not working

I am having a little bit of trouble binding the back end to the front end image. The image is dynamic. Here is the code on the back end that serves the front end:
public string currentCardImage
{
get
{
return currentCard.imageSource;
}
}
and the front end XAML for this is:
<Image Name="ImageMain"
Source="{Binding currentCardImage}"
HorizontalAlignment="Left"
Height="100"
Margin="368,529,0,0"
Grid.Row="1"
VerticalAlignment="Top"
Width="100"
RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<CompositeTransform Rotation="90.203" />
</Image.RenderTransform>
</Image>
Unfortunately this is not working. I can verify that there is data loaded into the currentCard and thus imageSource returns a location of the image.
Please let me know if you need more information. Any help is greatly appreciated!
EDIT: The c# code is in the XAML code behind
The reason why your binding fails is that Bindings are, by default, to the instance held within the DataContext property. So, the binding
{Binding currentCardImage}
actually means
this.DataContext.currentCardImage
Since you say the property is in the codebehind, I'm assuming your code looks something like this:
public sealed class MyClass : Window
{
public string currentCardImage
{
get { // SNIP!
In order to bind to this property, you have to redirect the binding to look to the root of the xaml tree (your Window) to start looking for the specified path.
The easiest way to do this is to name your root element
<Window x:Class="HerpDerp"
HideOtherAttributesBecauseThisIsAnExample="true"
x:Name="thisIsTheBindingTarget">
<!-- snip -->
and tell your Binding to look there
{Binding currentCardImage, ElementName=thisIsTheBindingTarget}

Categories