WPF Creating an instance of a class in xaml - wpf

I have a problem with creating the instance of a class in xaml file. I thought you can do it like this:
<src:MyDataClass x:Key="data"/>
in the resource part of the user control and then use it in the xaml file (for example bind to it).
But even tough the class I created is located in the same namespace it says that:
"The type was not found. Verfiy that all assemblies were built, etc".
How to get it right? is there another method?
Thanks for suggestions.

Well obviously you have to add the right namespace to your xaml. The namespace which contains the class you want instantiate. After reading this, you should be able to solve your problem.

Related

Fix XamlObjectWriterException, Cannot create unknown type in F#, FsXaml, WPF app?

I am getting this error in a WPF app that is built with F#, FsXaml, and Elmish.WPF.
System.Xaml.XamlObjectWriterException:
Cannot create unknown type '{http://schemas.componentone.com/winfx/2006/xaml}C1ProgressIndicator'.
at System.Xaml.XamlObjectWriter.WriteStartObject(XamlType xamlType)
at FsXaml.InjectXaml.from(String file, Boolean loadFromResource, Object root)
A Views project contains XAML and includes a reference to C1.WPF.4.dll.
The XAML declares an instance of a control from C1.WPF.4.dll.
However, there is no F# code that uses any types from C1.WPF.4.dll.
Consequently, Views.dll does not contain a reference to C1.WPF.4.dll, as confirmed by IL Spy.
Consequently, when I build App.exe, C1.WPF.4.dll is not included in the output folder.
Consequently, I get a run-time error.
While I could include a reference to C1.WPF.4.dll in my App project, I would rather not.
Is there a better way to do this?
To get this to work:
In your XAML file, replace the XAML namespace with a CLR namespace. For example, instead of xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml" use something like xmlns:c1="clr-namespace:C1.WPF;assembly=C1.WPF.4".
This is required because when App.exe is running, it may not have loaded the controls library yet. It is in the controls library that an attribute creates the mapping from XAML namespace to CLR namespace. By explicitly stating the CLR namespace and assembly, the XamlReader can find the class to instantiate.
Create a dummy instance in the Views code. The dummy instance is an instance of something from the controls library. This creates the dependency in Views.dll on the controls library.
// force the compiler to add a reference to C1.WPF.4.dll
let private forceC1DllReference = C1.WPF.Anchor.TopLeft
type MainWindowView = XAML< "MainWindow.xaml" >
This second one feels like a hack. I wonder if there is a better way to say, "Please add a reference to this DLL even if I'm not using types from it."

Set resource URI of .xaml component

I have a .xaml UserControl named MyUserControl.xaml and I want to set its resource URI.
Per default, WPF generates a URI that includes a resource name, which is equal to the resource it belongs to such as
"/MyNamespace;component/myusercontrol.xaml"
for the .xaml named MyUserControl.xaml
How can I have a UserControl MyUserControl.xaml and make WPF generate an individual resource identifies such as
"/MyNamespace;component/myusercontrol_A.xaml" or
"/MyNamespace;component/myusercontrol_B.xaml" ?
The reason why I want to do that is described here.
In the image below you can see the resource identifier I am talking about:
and therein:
Note, that that question is the origin of this question and might help to understand its background.
After a week suffering and laboring with this issue, I finally found both the reason for the problem and its solution.
The problem lies within the auto-generated *.g.i.cs file, which is called by the InitializeComponent() method of a UserControl, as seen by the following:
This file generates a string (a Resource Locator) that expresses the path to that xaml-component, as seen by the following:
Now, if you have multiple versions of the same assembly and both versions include the same xaml-file, WPF does not know what xaml-file to instantiate, because the Resource Locator only references the name of the assembly but not its version.
This results in a TargetInvocationException, saying that
{"The component 'MyNamespace.MyUserControl' does not have a resource identified by the URI '/MyAssembly;comoponent/myusercontrol.xaml'"}
as follows:
The simple (but most definitely not obvious) solution for this is to add the version of the assembly to this Resource Locator. This can be achieved by modifying the build-file of the project by adding the <AssemblyVersion>-tag as follows:
Credits for this go to:
this blog
this SO thread

Cannot find namespace

I found this article when challenged with a problem in one of my applications. I understand the usage, but cannot find the namespace for the local element where we find local:SetterValueBindingHelper.PropertyBinding. So what namespace does this reference? Google has not found the class either, nor MSDN. Thanks for the help!
Local just means an alias for a namespace in your own (or someone else's) code. E.g. say you took the SettingValueBingingHelper and saved it in your project, in the namespace MyNamespace. To use it in xaml you would reference the namespace by adding to your UserControl (or Page)
xmlns:local="clr-namespace:MyNamespace;assembly=MyAssembly"
It does't have to be local - it could be named anything that is relevant to your code, e.g. helpers.
Another example would be using the Triggers from System.Windows.Interactivity - you would reference the namespace:
xmlns:i="clr-namespace:System.Windows.Interactivity;
assembly=System.Windows.Interactivity"
and then use the triggers in your xaml:
<i:Interaction.Triggers>
BTW, the link in your original post has been updated.

XAML Resx localization not working as expected

I'm attempting to use a resx file to localize some strings I am using in a XAML file. I've looked around at other documentation on the web, and they all seem to recommend a two part process:
Add a clr-namespace to your window, like this:
xmlns:props="clr-namespace:PJConfiguration.Properties"
Use that namespace to localize your string like this:
Content="{x:Static props:Resources.SharedSettings}"
I've done this, and also made sure that my resource classes are public, but I still get the following error from the XAML in step 2:
Cannot find the type 'Resources'.
Does anyone know what else might be causing this problem? Thanks in advance.
In order to make the Resources visible to XAML, you have to make sure that the code generation mode for the resources is set to public. In VS, you find that setting in a ComboBox near the top of the Resources designer window.
For more information on using .Net resources in XAML, you might want to refer to these blog posts: http://wpfglue.wordpress.com/category/localization/
Check if your .resx file is the default Resources.resx file inside the Properties directory of the Application assembly. If that is, there is no reason XAML couldn't find the public class Resources from the correct namespace under local assembly.
Try to specify the assembly name in Step 2 as recommended in this answer.

WPF - Shut-off autogen of Main in App.g.cs

I'm learning WPF.
I want to provide my own Main method in my App.xaml.cs rather than getting one generated for me in App.g.cs. However I keep getting conflicts because I haven't found out how to stop an additional Main from being generated.
Is there a setting in my project file or elsewhere that controls this?
I found the answer here. http://learnwpf.com/post/2007/12/13/How-can-I-provide-my-own-Main%28%29-method-in-my-WPF-application.aspx
It is:
The way WPF knows to create the Main() method for a particular xaml file is through the build action property set for App.xaml - it has a build action of ApplicationDefinition. By changing this to Page WPF won't create the Main method and you can provide your own in a regular class file you add to the project.
However in the comments to the above blog, a comment notes there may be issues with blend and it references: http://blogs.msdn.com/expression/archive/2008/04/09/creating-a-wpf-blend-project-that-loads-resources-in-code.aspx . I don't fully understand the issues yet.
You can also just create a separate class (for example, Entry) which is responsible for bootstrapping your application. Then go to project settings and set your startup object to Entry. That way you don't even have to disable the autogenerated method.
The easiest way is to set the Build Action in the Properties window from ApplicationDefinition to Page for App.Xaml.
Then you can define your own entry point.
I found a solution:
Copy the data from your app.xaml file
Delete app.xaml file and re-create with the same name
Create `main` method in .cs file, and paste your old copied code into it
One way is to forgo defining an Application-derived class in XAML, so you can manually define the Main method with your custom requirement
The Easy way just create a class like Startup.cs with build action to compile
and remove ApplicationDefinition from App.xaml convert that to page
and remove it from any other file in the application

Resources