Can I prevent App.g.i.cs to be generated? - wpf

According to http://stuff.seans.com/2008/07/11/hello-wpf-world-part-1/, it is generated automatically.
Can I prevent to create it so that I can create my own version ?

In App.g.i.cs contains a function Main() is a standard entry point for an application and it is created automatically. If you want, you can provide your own class that implements Main() Link:
We can write in some other classes like Window1.xaml.cs. Then how the system identifies which Main() should get called. That too simple. Go to project properties, select application tab, then change the start up object to Window1.cs.
Here are the three approaches to add your own implementation of App.xaml:
Approach 1
You can delete the existing App.xaml and App.xaml.cs and add a new class file and maybe call it App.cs. In this you can define the App class and write your own Main method as below.
Approach 2
You will run into issues with Approach 1 if you are adding resources and resource dictionaries to your App.xaml. Since the App.xaml is no longer present you will have to write code in your App.cs itself to manage the resources and the merged dictionaries. However this can be more easily handled by modifying the .csproj file and marking App.xaml as Page instead of ApplicationDefinition.
Approach 3
If you have resources and hence want to have App.xaml, but don't like to tamper with .csproj file, then you can include another class in your project that defines the Main method as below.
Also, you can see this link:
Living Without App.xaml and still being able to use Blend

Related

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

XAML Unable to Read Values From Resx file

I have an composite application which has a Shell window and has some modules, each module is loaded on to the shell using MEF (Microsfot Prism). Shell Itself has a resource file default(Resource.resx) and for other languages(like Resource.ar-SA.resx) too to support Localilzation.
For Xaml : I had used x:Static Resource.KeyName
In c# Code : I had used GetString(keyName, culture) to get the required string.
To support Localization, I have added a line of code which gets the current culture of the system and loads the required Resx File.
For Setting the Current Culture.
Resource.Culture =
new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.Name);
in App.Xaml.cs
All these work Completely fine.
Similarly, each module which is loaded using MEF has Resource files as mentioned above. But in case of Modules, resource Key defined in the Xaml for a specific language file is not working. Its always getting the values from the Default (Resource.Resx) file. But any key used in the code using ResourceManager class works fine.
I ended up keeping all my resources in an "Infrastructure" project so all the resources are loaded from one place, it just made it simpler.
My xaml bindings look like this
Get the refrence to your resx class.
xmlns:resources="clr-namespace:Infrastructure.resources;assembly=Infrastructure"
now get the text
Content="{x:Static resources:Resources.Activity_Regarding}"
You might be doing this already but I cant see. You would want to make sure the namespace matches for the resx you want to use. So your modules namespace.

Remove an old namespace from a g.cs File?

I previously had a subfolder in my WPF application project called "Controls". It contained a WPF user control. I decided to move that user control to my "Views" folder. Since the original folder was empty, I decided to delete it from the project.
Because the user control and folder is removed I receive a compilation error because the user control used the ProjectName.Folder namespace and now nothing references it. MainWindow.g.cs is what references ProjectName.Controls in a using statement.
I know that *.g.cs are generated by VS and can't be edited because it will be overwritten. What do I do to not allow that namespace to be written to the g.cs file? I tried cleaning my solution/project and rebuilding but nothing has worked.
I had a local reference to the Controls namespace in my Xaml code (MainWindow.xaml). I removed the reference, cleaned the project and produced a successful build.
In your user control file,
In your ClassName.xaml, you must change the namespace as shown below
<UserControl
x:Class="YourOldNamespace.ClassName"
...
...
/>
And in your ClassName.xaml.cs, you must change the namespace as shown below
using System;
using System.Windows;
namespace YourOldNamespace{
public class ClassName{ ....
}
In both the files, you must replace YourOldNamespace to some new namespace as needed.
I have had problems with g.cs files in my projects before too. Since they are auto generated, I tend to just delete the file manually and rebuild.
Dont forget too, that you must check to see if the Build Action property when you click on the affected XAML file is set to PAGE (instead of resource). This is useful to know when you copy a XAML from another project using copy-paste to save time.
Also look at App.xaml and all of your resource dictionaries. For whatever reason, VS 2012's replace in files / "Entire Solution" option didn't find the old namespace reference in App.xaml, had to manually change that. Fixed it for me.
Don't forget to change your Generic.xaml file too,
<ResourceDictionary
xmlns:local="clr-namespace:MyOldNameSpace">
</ResourceDictionary>

WPF: How should I organize my code amongst the source files?

I see a Window1.xaml and its associated .cs file, which are the main window. Then there's also app.xaml and app.xaml.cs. First, what is the point of App? It seems to be empty.
I'm assuming I should put local variables to the Window on its cs file, and variables related to the whole program on App?
You should MVVM. Start early, win often.
App.xaml and its code file are used for application-wide resources and code that needs to run on startup. You shouldn't be putting anything in app.xaml.cs unless you need to.
App.xaml and App.xaml.cs is your applicaton's entry point. Main() is actually auto-generated and hidden in the partial App class. In the XAML, you can set the Window that will initially display, so you are not forced to use Window1.
In reality, you don't need App.xaml either. In some applications I have made, I have instead opted to create an App.cs, where I manually create the Main() entry point and start the initial Window. If you don't need such fine control over your Main() method, I'd recommend keeping the default XAML method of startup. You can still subscribe to events in App's constructor using the XAML method, for startup code and handling unhandled exceptions.
You should put local variables with the class that needs them. Global variables are bad, but it's be better to use static classes and variables instead of inserting the unnecessary code in App.xaml.cs.

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