I have WPF project and some resources defined in App.xaml that are used in other files. When I try to move App.xaml to subdirectory designer is no longer able to find those resources. My project still compiles since I use 'Startup' event instead of 'StartupUri'. How to tell the designer where to search for resources? How it knows where they are when App.xaml is in root of project?
Update:
Project files:
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="startup">
<Application.Resources>
<SolidColorBrush Color="LightGray" x:Key="brush" />
</Application.Resources>
</Application>
App.xaml.cs
namespace WpfApplication1
{
public partial class App : System.Windows.Application
{
private void startup(object sender, System.Windows.StartupEventArgs e)
{
new MainWindow().Show();
}
}
}
MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" Background="{StaticResource brush}" />
MainWindow.xaml.cs
namespace WpfApplication1
{
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
Update 2:
Uploaded zipped solution to http://zalil.ru/30771604 (download will start automatically)
Mirror: http://www.speedyshare.com/files/27697250/WpfApplication1.zip
1. Move you App.xaml to your desired location
2. Refactor you App.xaml.cs namespace to accommodate the new change:
3. Rebuild your solution.
[4]. Go to your project properies and set the Startup object to your App.xaml file at the new location.
[5]. Run your application and it should work successfully :)
I can't duplicate the problem on my end. Here's what I tried:
I created a application with a style in the resources of App.xaml. I moved App.xaml to a subdirectory. I have another window that uses the style defined in the resources of App.xaml (he resides in a different directory) and it was able to resolve it just fine. I added ..\ to the beginning of my original StartupUri.
I did some searching, what version of Visual Studio are you using? Apparently there may be an bug related to your problem in VS2008:
http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored
He says a workaround for this bug is to set the x:Name attribute on Application. Hope that helps!
EDIT: I also tried handling the Startup event instead of using the StartupUri and it still worked fine.
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
new MainWindow().Show();
}
}
EDIT PART 2:
Okay, I enclosed the SolidColorBrush inside a ResourceDictionary as such:
<ResourceDictionary>
<SolidColorBrush Color="LightGray" x:Key="brush" />
</ResourceDictionary>
And the window picks up the brush. The designer doesn't like it, but when I change from StaticResource to DynamicResource it stops complaining.
EDIT 3:
I just thought of something. Do you have VS2010 SP1 installed? It fixed some bugs with the designer.
And sorry, my edit number 2 didn't work as expected. I noticed my blue squiggles were gone in the xaml, but I didn't check the designer. x__x
Related
Problem: The resource dictionary does not load at run time, but displays correctly in the designer. If I change the color in Dark.xaml to green, I can notice in the designer that my Window background (Layout.xaml) turns green. but when I compile the project in Debug mode, the background is just transparent !!
What I have tried in App.xaml:
<Applicationxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StackOverflow" x:Class="StackOverflow.App">
<Application.Resources>
<ResourceDictionary Source="#"/>
</Application.Resources>
</Application>
And:
<Applicationxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StackOverflow" x:Class="StackOverflow.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="#"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
In the source value, I tried these 3 possibilities:
Theme/Dark.xaml
/StackOverflow;component/Theme/Dark.xaml
pack://application:,,,/StackOverflow;component/Theme/Dark.xaml
App.xaml.cs:
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
Window Window = Server.Status() is StatusCode.OK ? new Layout() : new Login();
Window.ShowDialog();
Current.Shutdown();
Dark.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="StackOverflow.Theme.Dark" xmlns:local="clr-namespace:StackOverflow.Theme">
<SolidColorBrush x:Key="Layout.Background">Red</SolidColorBrush>
</ResourceDictionary>
Dark.xaml: File Properties
Build Action: Page
Copy to Output Directory: Do not copy
Custom Tool: XamlIntelliSenseFileGenerator
Custom Tool Namespace:
Dark.cs:
namespace StackOverflow.Theme {
public partial class Dark : ResourceDictionary {
public Dark(){
InitializeComponent();
}
}
}
Dark.cs: File Properties
Build Action: Compile
Copy to Output Directory: Do not copy
Custom Tool:
Custom Tool Namespace:
Note: These two files (Dark.xaml / Dark.cs) are nested using the File Nesting extension (Keith Wilson).
Layout.xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StackOverflow.XAML"
x:Class="StackOverflow.XAML.Layout"
Background="{DynamicResource Layout.Background}"
AllowsTransparency="True"/>
Project File Structure:
XAML
Layout.xaml
Theme
Dark.xaml
App.xaml
Other information:
Solution Configuration: Debug
Solution Platform: x64
Microsoft Visual Studio Community 2019 v16.7.3
Update:
For some reason the problem reappeared with the Application StartUpUri, if you noticed that I didn't use this attribute because I have to verify the user's login before giving them access to the main window. So behind the code in App.xaml.cs I call Login.ShowDialog() and Layout.ShowDialog(). After setting this attribute to Layout Window, I can notice that the application is consuming the resources defined under Dark.cs, so if I change this line:
<SolidColorBrush x:Key="Layout.Background">Lime</SolidColorBrush>
The layout background changed at runtime to the color Lime, but I'm wondering if it is possible to use the same resources defined in App.xaml in all project windows, in my case StartUpUri will be Login.xaml, and under Login if the user info is correct I can prevent this window from showing and show my layout window. but the question here is whether this resource named "Layout.Background" can be used in both windows?
I got the idea that the app resource dictionary defined in App.xaml is like a super global resource, which I can use whenever I want. Is it correct? because this result does not seem to support it.
I am trying to us the demo code from wpf chrometabs and in the other application I just added a button that calls the constructor of the demo:
private void FrontendDebug_Click(object sender, RoutedEventArgs e)
{
Demo.MainWindow mainWindow = new Demo.MainWindow();
mainWindow.Show();
}
The problem is that it throws an exception at the InitalizeComponent:
I read somewhere that in MVVM, the DataContext should be set before calling InitializeComponent() but I don't know if that is the problem here or how to do it if it is.
The error that you get points out, that you use a StaticResource markup extension to reference a resource with key Locator that is not found in this line:
DataContext="{Binding Source={StaticResource Locator},Path=ViewModelMainWindow}"
The locator is defined in the application resources, so it is accessible in the whole application. Either you accidentially removed it or there is a typo in App.xaml. Make sure that it looks like this.
<Application x:Class="Demo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:Demo.ViewModel" />
</Application.Resources>
</Application>
I am trying to us the demo code from wpf chrometabs and in the other application I just added a button that calls the constructor of the demo:
If you have another application that uses the demo project as library, the call below will only create an instance of the MainWindow. It will not bootstrap the application in the demo project.
Demo.MainWindow mainWindow = new Demo.MainWindow();
Consequently, the App object from the demo project is never created and its resources are not available. Even if it would be bootstrapped, the resources defined in App.xaml only apply to this application, nothing else.
Therefore, the mainWindow instance will try to find the resource in your application, not in the demo application. Since it is not defined there, you will get an exception. You could add the view model locator to your application's App.xaml resources, but keep in mind that is applies to all resources defined on the application level.
I have some custom converters for my wpf dialog.
All of sudden i get this message:
The Name "BoolToVisibilityInversConverter" is in the Namespace "clr-namespace:plans.SeqOpDialog.Converter;assembly=plans.SeqOpDialog" not available
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:plans.SeqOpDialog.Converter;assembly=plans.SeqOpDialog">
<conv:BoolToVisibilityInversConverter x:Key="btvInvConv"/>
<conv:TimeSpanConverter x:Key="timeConv"/>
<conv:BoolToVisibilityConverter x:Key="btvConv"/>
<conv:BoolInversConverter x:Key="BoolInversConverter"/>
</ResourceDictionary>
A class as Example:
namespace plans.SeqOpDialog.Converter
{
public class BoolToVisibilityInversConverter : IValueConverter
{...
}}
I cleaned the project, restarted VS and i'm out of ideas what i could do
Did you miss the Converter?
xmlns:conv="clr-namespace:plans.SeqOpDialog.Converter;assembly=plans.SeqOpDialog.*Converter*">
I have a solution with three projects. One is for Testing using CodedUI, the other is a WPF Viewer application that shows the data from the tests, and the third is a project of Models.
If I set the WPF project to be the start up project in the solution and run it in debug mode the theme shows up just fine.
If I attempt to start the WPF MainWindow from the Test Project, everything shows the same, without the Theme. When the test project wants to show the data it does so by firing an event to this method in the WPF project.
public static class Start
{
public static EventHandler<List<SomeData>> NewData = ShowData;
private static void ShowData(object sender, List<SomeData> e)
{
MainWindow.NewData(sender, e);
var mw = new MainWindow();
mw.ShowDialog();
}
}
I have single stepped through this code, the data arriving and the mainwindow coming up just fine. But why wouldn't the code above include the theme?
There are no loading errors in output window.
The App.XAML is where the reference to the theme is located. But it is also where the StartupURI is located which is MainWindow.XAML. Do I need to somehow start App.XAML to get the theme?
Please advise...
How to start a WPF application and ensure the Theme works! (given the situation mentioned above)
var app = new App();
app.InitializeComponent();
app.Run();
Where App is your WPF application found here ==> App.xaml/App.cs and App.gs.i.cs.
The InitializeComponent call was the key. In the gs file this line is does the magic.
System.Windows.Application.LoadComponent(this, resourceLocater);
Notice the "this" keyword. It is a reference to the App class itself which in the XAML have these "references/attributes/resources"
<Application x:Class="AuomatedTest.Viewers.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/ExpressionDark.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The Theme itself was located in the project with these build attributes:
The bin directory had no folder named "Themes" in it; rather, it was the obj folder that contained the Theme; however, it was the "compiled" version of the file denoted by the .baml extension.
This means that the Page attribute of the XAML file compiles it. But what it doesn't tell us is how a reference like this is adequate.
<ResourceDictionary Source="Themes/ExpressionDark.xaml">
Today we know that without the Application.LoadComponent being called from the place we referred to the Theme (App.Xaml)that no Theme will be displayed. LoadComponent then knows how to interpret .BAML files and treat them as if they actually existed in the location that was referenced.
I have project in WPF.
The problem is, when I move App.xaml file to subfolder, it doesn't want to compile because it can't find main method.
How to force Project to start application with window set in App.xaml file as StartUp Window?
I use Visual Studio 2010 express.
edit:
My App.xaml
<Application x:Class="TraceabilityLoader.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="View/VmainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Subfolders in project:
View, Model, ViewModel etc....
I resolve this issue with custom Startup Window using OnStartup:
App.xaml
<Application x:Class="Pin.Visualisation.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="OnStartup">
<Application.Resources>
</Application.Resources>
</Application>
App.xaml.cs
namespace Pin.Visualisation
{
public partial class App : Application
{
private void OnStartup(object sender, StartupEventArgs e)
{
var view = new MainWindow();
view.Show();
}
}
}
My MainWindow stores in View/MainWindow. Is it useful for you?
Ok, I found resolution for my problem.
After moving App.xaml to other folder visual studio's changed Build Action from application definition to Page.
Changing it back solves problem.
The class containing your main method (App.xaml, App.xaml.cs) have to be in the root of your startup project for them to be automatically detected.
If you want them in a sub folder, you have to manually specify the startup object:
Right click project
Navigate to the Application settings tab
Select from the startup object dropdown.
By convention, your startup object really should be in the root.
If you just wanna move the App.xaml to a subfolder because you wanna organize the structure. You can just leave the namespace to your first level.
namespace WpfApplication3 <-----
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
If not you have to do as #Gusdor