Could not find ObjectDataProvider when localizing wpf - c#

I have a project along with main project in my solution. I want to localize the content in this xaml file in this project.
I use the ways that have been discussed here How to change UI language using resource dictionary at run time in MVVM?.
However I could not find ObjectDataProvider in any way.
<UserControl xmlns:languageHelper="clr-namespace:XX"
<UserControl.Resources>
<ObjectDataProvider x:Key="Resources" ObjectType="{x:Type languageHelper:CultureResources}" MethodName="GetResourceInstance"/>
</UserControl.Resources>
</UserControl>
and I use this code to find ObjectDataProvider but i coulnt get it through
public static ObjectDataProvider ResourceProvider
{
get
{
if (m_provider == null)
m_provider = (ObjectDataProvider)System.Windows.Application.Current.FindResource("Resources");
return m_provider;
}
}
Resources.Culture = culture;
ResourceProvider.Refresh();
It shows System.Windows.ResourceReferenceKeyNotFoundException: ''Resources' resource not found.'

Well the problem is that you are creating your ObjectDataProvider in your UserControls resources. I think you have to create that in your App.xaml file
here is an example:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ObjectDataProvider x:Key="Resources"
ObjectType="{x:Type languageHelper:CultureResources}"
MethodName="GetResourceInstance"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

Related

WPF – Insert Resource Dictionary in C# into XAML

By this way I can access XAML resources in C# code:
var resource = new ResourceDictionary
{
Source = new Uri("/myAssemblyName;component/Themes/MyStyle.xaml", UriKind.RelativeOrAbsolute)
};
I thinking about a reverse approach. I would like define resource dictionary in C# code like this:
public class MyColors : ResourceDictionary
{
public MyColors ()
{
this.Add("MyGreen", Color.FromRgb(10, 211, 12)); // this["MyGreen"] = Color.FromRgb(10, 211, 12);
}
}
And then include this resource dictionary into XAML style file like this:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyColors.cs" />
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="MyGreenBrush" Color="{StaticResource MyGreen}" />
</ResourceDictionary>
The question is about possibility of including resource dictionary into XAML file. Because presented approach not working – error: Unexpected project file type at …\MyColors.cs.
You need to construct your created class inside MergedDictionaries
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<yourClassXmlNamespace:MyColors/>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="MyGreenBrush" Color="{StaticResource MyGreen}" />
</ResourceDictionary>
you should build the dictionary in XAML
this will look as follows
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_ScratchPad">
<Color x:Key="MyGreen">#0ad30c</Color>
</ResourceDictionary>
then as your are correctly doing you merge the controls dictionary
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyColors.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
If you really need to create your dictionary in code then you would merge it as follows
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<yourxmlns:MyColors/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
once you have added the dictionary to the control you don'[t need to instantiate a separate instance of the dictionary to access it instead just call TryFindResource as this keeps the override structure intact

Using (merged) Resource Dictionary in C# Class Library Project

How can I use a (merged) WPF Resource Dictionary in a C# class library project?
Here is what I did:
In my C# class library project I have a file Dictionary1.xaml like that:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style x:Key="PluginFrameBorderStyle">
...
</Style>
</ResourceDictionary>
Then, I have a UserControl file UserControl1.xaml where I try to use the Dictionary like that:
<UserControl x:Class="EditorPackageA.BackboneMemberB1Editor.BackboneMemberB1Editor"
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"
mc:Ignorable="d"
xmlns:local="clr-namespace:EditorPackageA.EditorBase"
xmlns:prism="http://www.codeplex.com/prism" d:DesignWidth="690.4" d:DesignHeight="460.12">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
...
</UserControl>
The project compiles but at runtime I get the error:
with the exception detail:
The same approach works when applied within a WPF project rather than a Class Library project.
What might be the solution here?
Important Addendum:
During design-time I see the effect of the used style that is embedded via the ResourceDictionary, hence the URI of the style and the dictionary must be correct!?
Try to use so called pack URI. I think that you have to explicitly specify where the resource dictionary is located.
<ResourceDictionary Source="pack://application:,,,/TheNameOfClassLibrary;component/Dictionary1.xaml"/>
In the case of a WPF project your approach works because WPF engine by default looks for resource in the assembly being executed (in exe).
You should refer/link the ResourceDictionary xml file to the Source attribute with assembly and component name.
Use relative path as follows:
<ResourceDictionary Source="../Dictionary1.xaml" />
If it is not working, then try PACK URL
<ResourceDictionary Source="pack://application:,,,/Your.Base.AssemblyName;component/DictionaryFolder/Dictionary1.xaml" />
Hope it helps you
You probably need to merge your library's resource dictionary in your application resources. You need to edit your App.xaml file and add something like:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/YourAssembly;component/Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

How to place XAML-only resources in a DLL (Reference) file to be used by WPF applications?

My WPF applications are reaching the level of complexity at which it becomes desirable to place some of the code and other resources inside a Reference file (*.dll).
I am sure I can figure out how to do this, by following the myriad applications out there.
In this particular case, however, the files are two, XAML:
Can somebody please provide an example on how to expose or publish the XAML resources? Are *.cs files required?
TIA
The XAML file outlined by #HighCore should look like this:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
XAML ResourceDictionaries do not generate classes. I'm not sure why you would expect such thing.
Simply move the needed ResourceDictionary definitions to a separate assembly then use the Pack URI Syntax to merge these resources to your application's Resources in app.xaml:
<Application ....>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

ResourceReferenceKeyNotFoundException declared on Dictionary.xaml

I have an ObjectDataProvider declared on a dictionary:
<ObjectDataProvider x:Key="Resources"
ObjectType="{x:Type const:CultureResources}"
MethodName="GetResourceInstance"/>
And I have a class that wants to find it like this:
m_provider = (ObjectDataProvider) App.Current.FindResource("Resources");
But when it tries to find the Resource, it launches the error
ResourceReferenceKeyNotFoundException
And can't find my resource... Here you have an image on how my project is divided:
The Default.xaml is my default dictionary.
So, why I can't find my Resources element defined on my dictionary?
I need to answer my question, because it was such a weird thing...
At first, I need to say that I had to add my Dictionary.xaml to my App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../themes/Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
For some reason, it wasn't enough to call it on my MainWindow.xaml. So I erased it from my MainWindow.xaml and added it to App.xaml, but I couldn't have them inserted in both sides. That was the part that I couldn't see clearly...

wpf image resources and changing image in wpf control at runtime

I would like to know exactly how to dynamically use a Dictionary Resource in the C# code behind - ie.. I would like to load images at runtime from an image resource within a dictionary
I have a program that has 3 images in a WPF Dictionary - these are images set as image resources.
Then in the code behind of my WPF Window I want to load any one of the three images based on user initiated events.
There is no real code I have to show as nothing that I have done works.
Ideas?
First, make sure you've defined your image resources like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ImageSource x:Key="image1">images/image1.jpg</ImageSource>
<ImageSource x:Key="image2">images/image2.jpg</ImageSource>
</ResourceDictionary>
Secondly, I'm assuming that your WPF dictionary is in its own file. Now you have to make sure you've merged your dictionary into your main window's XAML (skip this step if your resource dictionary is defined inside of the window's XAML). In your window's XAML file, make sure you have something like this:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Now, in your code-behind, you can use the FindResource() method to locate your image resource by it's key name (the value of the x:Key attribute on the ImageSource in the resource dictionary) like so:
imageControl.Source = (ImageSource)FindResource("image1");
Hope this helps!
This is an addition to the accepted answer:
When working within a ViewModel from MVVM, make sure to use the FindResource from the view where the resource directory is added.
<Window x:Class="My.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:My.ViewModels"
Title="USA Hockey Player Evaluation tool"
Icon="/USAHockeyPlayerEval;component/View/Images/HET.ico"
SizeToContent="WidthAndHeight"
MinHeight="500px" MinWidth="800px">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Images.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<ViewModels:MainWindowMV/>
</Window.DataContext>
<StackPanel>
<Menu>
<MenuItem Header="File">
<MenuItem Header="Save"></MenuItem>
My view in this case is a window (I know not correct MVVM ;-) )
Image img = new Image();
img.Source = (ImageSource)WindowReference.FindResource("Pluse");
Here the WindowReference is a reference to My.MainWindow.

Categories

Resources