Using Uri for a Different Assembly to Load an Image - c#

Search around for sometime but can't seem to figure out as to why I can't load an image from a different project in the same solution.
I have logo images put in a separate project(assembly) as shown below:
namespace LogosModule
{
public static class TestClass
{
public static readonly Uri Hess = new Uri("pack://application:,,,/LogosModule;component/Resources1/Logos/Hess.jpg", UriKind.RelativeOrAbsolute);
}
}
The file build action is set to "Content". I have also tried to use "Embedded Resource" while copying to root directory enabled.
The Uri is assigned at the constructor. I have also tried to hardcode the Uri to no avail.
In my main Shell module, I have an AboutView control that is used to have this image displayed (using Catel here):
[ViewModelToModel(nameof(AboutInfo))]
public Uri AssociatedCompanyLogoUri
{
get { return GetValue<Uri>(AssociatedCompanyLogoUriProperty); }
set { SetValue(AssociatedCompanyLogoUriProperty, value); }
}
public static readonly PropertyData AssociatedCompanyLogoUriProperty = RegisterProperty(nameof(AssociatedCompanyLogoUri),typeof(Uri));
I have another image but this one is included in the main Shell assembly and it displays with no problem using the same approach.
The XAML code is shown below:
<StackPanel Grid.Row="0" Grid.Column="0" Margin="10,5,0,10" Orientation="Horizontal">
<TextBlock Text="Account" FontSize="32" Margin="10,5,0,10"></TextBlock>
<Image Source="{Binding AssociatedCompanyLogoUri}" HorizontalAlignment="Right"
Margin="10" VerticalAlignment="Center" Stretch="None" />
</StackPanel>
The exception I get is shown below:
Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "LogosModule.g.resources" was correctly embedded or linked into assembly "LogosModule" at compile time, or that all the satellite assemblies required are loadable and fully signed.
at System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(String fileName)
While debugging, I can clearly see that the Uri is assigned. The problems seems to be that the assembly somehow isn't loaded properly.
Help is appreciated it.

The Build Action of the Image should be set to Resource in the LogosModule project.
Then it should provided that the name of the assembly is "LogosModule" and that there actually is an image called "Hess.jpg" in the Resources1/Logos folder of the "LogosModule" project and that you have set the AssociatedCompanyLogoUri source property like this:
AssociatedCompanyLogoUri = LogosModule.TestClass.Hess;

Related

"The member "X" is not recognized or is not accessible." error in WPF

I'm trying to make an interface with multiple language options on a WPF screen. I'm writing the name of the text block I want to add to my Resources file and my code, but on the xaml screen "The member "Manuals" is not recognized or is not accessible." I get an error. I am getting this error in all the buttons and texts I try to add. Can you help me understand why? There is my xaml code line and resources designer cs project code line. Thanks in advance.
public static string _Manual
{
get
{
return ResourceManager.GetString("Manuals", resourceCulture);
}
}
<TextBlock Name="ttbManuals" Grid.Row="8" Text="{x:Static resx:Resources._Manual}" HorizontalAlignment="Left" Margin="0,0,0,-20" VerticalAlignment="Top" Height="39" Width="580" Style="{DynamicResource CncTextBlock}" Background="{DynamicResource BackgroundBrush1}" Padding="10,5,0,0"/>
The Resources class is by default created as internal. For use in XAML it needs however to be public.
To fix it, select the resx file in solution explorer and in the properties, change ResXFileCodeGenerator to PublicResXFileCodeGenerator.
See also here: Visual Studio - Resx File default 'internal' to 'public'

UWP, my app crashes for the image path when built , but when I run it on the debugger it works fine

I'm creating a UWP that receives the image path from a static class. It works fine when I'm debugging it, but when built, the application crashes.
I have tried with a lot of different ways of accessing the image path from code behind (Uri, BitmapImage, etc.) which has been defined by the selected object. Below, you can see the code that has allowed me to do it. The try and catch was a way for me to notice if that was what had been crashing the application.
try
{
ImageSource result = new BitmapImage(new Uri("ms-appx:///" +
EntriesDone.SelectedEntry.ImagePath));
img_entry.Source = result;
img_entry.Opacity = 0.40;
img_entry.MaxWidth = 500;
img_entry.MaxHeight = 500;
}
catch (Exception)
{
txt_Name.FontSize=2;
}
What I would like to know is if there is a better way for me to access the image path or the assets folder allowing the object to define the image that will be shown (there are more than 60 entries so I need to do it efficiently) and that won't crash the application upon being built. I'd also like to know why this crashes the application when built. Thanks!
What I would like to know is if there is a better way for me to access the image path or the assets folder allowing the object to define the image that will be shown
For your requirement, you can use DataTemplate and ListView (or GridView) to show the images.
create data model:
public class ImageModel
{
public string ImageUrl { get; set; }
// Other properties
...
}
In the code-behind file of the page, create a new collection and fill the data:
// ObservableCollection can notify UI when collection item changed
public ObservableCollection<ImageModel> ImageCollection = new ObservableCollection<ImageModel>();
public TestImagePage()
{
this.InitializeComponent();
ImageInit();
}
public void ImageInit()
{
// Load image model here.
// e.g.
ImageCollection.Add(new ImageModel{ImageUrl="ms-appx:///Assets/image.png"});
}
Create DataTemplate and GridView on XAML:
<Page
...>
<Grid>
<GridView ItemsSource="{x:Bind ImageCollection}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ImageModel">
<Image Opacity="0.4"
MaxWidth="500"
MaxHeight="500"
Source="{x:Bind ImageUrl}"
/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Page>
The process I provide is very simple, you can expand this code according to your needs.
Best regards.

Displaying an Image on a WPF page

I am trying to display an image on a WPF page. The code is shown below:
<Grid>
<TextBlock Margin="32,332,395,74" Cursor="None">
Click to <Hyperlink NavigateUri="TestWindow.xaml">sign a document</Hyperlink>
</TextBlock>
<Image HorizontalAlignment="Left" Height="151" Margin="32,96,0,0" VerticalAlignment="Top" Width="179"
Source="signature.png" Visibility="Visible" Name="signImage"/>
The problem is the image shows in WPF designer but when I run the program, the image does not display on the page.
Note the image is displayed on a PAGE not a WINDOW
Another option is to use a resource, e.g. in your app.xaml:
<Application.Resources>
<BitmapImage x:Key="signatureSrc" UriSource="/MyProject;component/ImageFolderIfThereIsOne/signature.png" />
</Application.Resources>
and use it like this
<Image Height="100" VerticalAlignment="Top" Width="100" Source="{StaticResource signatureSrc}" />
Try this out PackURIs
Image finalImage = new Image();
finalImage.Width = 80;
...
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png");
logo.EndInit();
...
finalImage.Source = logo;
The URI is broken out into parts:
Authority: application:///
Path: The name of a resource file that is compiled into a referenced assembly. The path must conform to the following format: AssemblyShortName[;Version][;PublicKey];component/Path
AssemblyShortName: the short name for the referenced assembly.
;Version [optional]: the version of the referenced assembly that
contains the resource file. This is used when two or more referenced
assemblies with the same short name are loaded.
;PublicKey [optional]: the public key that was used to sign the
referenced assembly. This is used when two or more referenced
assemblies with the same short name are loaded.
;component: specifies that the assembly being referred to is
referenced from the local assembly.
/Path: the name of the resource file, including its path, relative to
the root of the referenced assembly's project folder.
The three slashes after application: have to be replaced with commas:
Note: The authority component of a pack URI is an embedded URI that
points to a package and must conform to RFC 2396. Additionally, the
"/" character must be replaced with the "," character, and reserved
characters such as "%" and "?" must be escaped. See the OPC for
details.
And of course, make sure you set the build action on your image to Resource.
Frustrated with this myself, I just figured out the the page uses a relative location for the image. In my case, the image was in the folder "Graphics/logo.jpg", and the page was in the folder "View/Setting/About". I updated the Source of the image to ../../Graphics/logo.jpg and it worked.

WPF Image won't show in Class Library Project

I can't display an image on WPF window during runtime. However, it is shown during design mode. The image is located in Images folder and Build action is set to Content as well is Copy to output to Copy Always. The output Any suggestions?
===EDIT====
The output type of a project is : Class Libray, if I change it to Window Application the bellow are workign fine. However I still need to build it is Class library.
2nd try
<Image Source="pack://siteoforigin:,,,/Images/Logo2.png" Grid.Row="0"/>
3rd try
<Image Source="pack://application:,,,/Images/Logo2.png" Grid.Row="0"/>
Also,
If I put a full path to the image location it is working, apparently this is not ideal situation:
<Image Source="C:/.../Images/Logo2.png" Grid.Row="0"/>
Rebuild your entire solution and try again. It probably didn't do a build with images in it when you tried it again.
Also use your 3rd try again then build action to content, no need to make a copy always.
After several trials the answer was quite simple:
For Class Library Project set your images Build Action to Resource and get a reference in Xaml as:
<Image Source="/YOURNAMESPACE;component/Images/Logo.png"/>
It won't work with png, but convert to jpg and write:
<Image Source="/YOURNAMESPACE;component/Images/Logo.jpg"/>
That works for me :)

How to get a Uri of the image stored in the resources

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.

Categories

Resources