When I include an assembly containing a ResourceDictionary using the following pack syntax:
"pack://application:,,,/WpfCore;component/ResourceDictionaries/ThemedControls.xaml"
It works as expected, but as soon as I add a code behind file to the XAML of the ResourceDictionary, the following error is thrown:
“An error occurred while finding the resource dictionary”
The code behind is added to the XAML in the usual way:
< ResourceDictionary x:Class="com.mycompany.WpfCore.ResourceDictionaries.ThemedControls"
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">
</ResourceDictionary>
and looks like this:
namespace com.mycompany.WpfCore.ResourceDictionaries
{
public partial class ThemedControls : ResourceDictionary
{
public ThemedControls ()
{
InitializeComponent();
}
}
}
Intuition tells me this is a namespace problem, but all the variations I've tried fail. What am I doing wrong or is this a limitation of WPF ResourceDictionaries?
Edit:
Seems the question detail was called out and found to be wanting.
The initial example had the namespace simplified. The default namespace for the WpfCore project is com.mycompany.WpfCore which I have now added into the code examples above.
The ThemedControls.xaml and ThemedControls.xaml.cs files are located in a subfolder called ResourceDictionaries within the WpfCore project folder.
The resulting assembly is used as a referenced assembly in another solution and this is where the Pack URI is being used.
Edit 2:
After playing around with the build action for the xaml files (changing from page to resource and back again) things started working. Marking Sheridan's answer as correct.
I don't think that you have declared your ResourceDictionary quite correctly... the application name really should be in the namespace. This should work... at least it works for me:
<ResourceDictionary
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"
x:Class="WpfCore.ResourceDictionaries.ThemedControls">
</ResourceDictionary>
Code behind:
namespace WpfCore.ResourceDictionaries
{
public partial class ThemedControls : ResourceDictionary
{
public ThemedControls()
{
InitializeComponent();
}
}
}
Related
I have a question for people familiar with the Community Toolkit MVVM regarding best practices for building up the Views part of MVVM. I have started a new project to try to get things figured out before trying to implement this into my actual project. My main question is, if you have multiple views/windows for different purposes in a WPF application, is it not a good idea to place them into a View or Views folder? If so, I'm having a hard time getting the application to launch the main window.
System.IO.IOException: 'Cannot locate resource 'wpf_mvvm_test.views.mainwindow.xaml'.'
The first thing I tried was just moving the MainWindow.xaml file to the views folder, which caused the runtime error as soon as it compiled. I started changing the namespace references for the MainWindow.xaml, MainWindow.xaml.cs, App.xaml, App.xaml.cs, as well as the startup URI to reflect the namespace for the folder, WPF_MVVM_Test.Views, and none of the changes I have made have prevented the error. I did leave the App.xaml file in the main project, not in the folder. If I try to move it into the Views folder, even if I change its x:Class and the App.xaml.cs namespace to WPF_MVVM_Test, when I try to run it, it gives me an error that there is no static Main entrypoint.
Is there no way to place the WPF window files into a folder? If it's not possible, it's not possible, but if it is possible, I would love to figure out how, as it would make it easier to keep the solution organized.
MainWindow.xaml:
<Window x:Class="WPF_MVVM_Test.Views.MainWindow"
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:WPF_MVVM_Test.Views"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
MainWindow.xaml.cs:
using System.Windows;
using WPF_MVVM_Test.ViewModels;
using WPF_MVVM_Test.Views;
namespace WPF_MVVM_Test.Views
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
}
App.xaml:
<Application x:Class="WPF_MVVM_Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_MVVM_Test"
StartupUri="WPF_MVVM_Test.Views.MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
App.xaml.cs:
using System.Windows;
using WPF_MVVM_Test.Views;
namespace WPF_MVVM_Test
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
Thanks to ASh for the very helpful reply. I'm not sure what is preventing the application from compiling by moving the MainWindow.xaml file in to a folder, but the workaround references ASh provided definitely works.
First, I removed the StartupUri statement from the App.xaml file.
Second, in the App.xaml.cs file, I added an override for an OnStartup event as shown below, ensuring the folder that the MainWindow files are located in is in the using statements.
App.xaml.cs
using System.Windows;
using WPF_MVVM_Test.Views;
namespace WPF_MVVM_Test
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new MainWindow().Show();
}
}
}
I have a windows phone project where I've added a usercontrol:
namespace MyApp.WindowsPhone.UserControls
{
public partial class SlidingUpOverlay : UserControl
{
public SlidingUpOverlay()
{
InitializeComponent();
}
}
}
Then I'm referencing it in a Page like this:
<phone:PhoneApplicationPage
x:Class="MyApp.WindowsPhone.UI.TopUpPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:userControls="clr-namespace:MyApp.WindowsPhone.UserControls">
<userControls:SlidingUpOverlay x:Name="SlidingUpOverlay" Visibility="Collapsed" />
But building it gives me following error:
The type or namespace name 'UserControls' does not exist in the namespace 'MyApp.WindowsPhone.MyApp.WindowsPhone' (are you missing an assembly reference?) MyApp-WP C:\Users\MyApp\developers\apps\MyApp-WP\MyApp-WP\obj\Debug\UI\TopUpPage.g.i.cs
I've cleaned bin and obj-folders, restarted computer, restarted VS2015, tried everything suggested but nothing works. I've also read through many pages here on stackoverflow but haven't found anything the suggests anything else than I've already tried. What am I missing?
xmlns:userControls="clr-namespace:MyApp.WindowsPhone.UserControls"
You could try changing this line to:
xmlns:userControls="using:MyApp.WindowsPhone.UserControls"
Change the namespace of user control:
namespace MyApp
{
public partial class SlidingUpOverlay : UserControl
{
public SlidingUpOverlay()
{
InitializeComponent();
}
}
}
Then add the following reference in your Xaml Page:
xmlns:userControls="clr-namespace:MyApp">
P.S. Also change the Xaml schema of your User control
x:Class="MyApp.SlidingUpOverlay"
I find very frequently that while I'm 'prototyping', and I change the base type of the code behind class, or something like that, that the two files become completely unaware of each other. Example:
XAML:
<UserControl x:Class="G4S.XTime.Modules.Employees.Details.Views.EmployeeGridView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
Code-behind:
namespace G4S.XTime.Modules.Employees.Details.Views
{
public sealed partial class EmployeeGridView: UserControl
{
public EmployeeGridView()
{
//InitializeComponent();
}
}
}
The call InitializeComponent produces a compile time error, saying it doesn't exist.
This disconnect phenomenon happens often enough to be costing me time, and I often just copy the code out of both files, delete the view, add a new view with the same name, paste the same code back, and everything works.
What am I missing that connects the two files? In the project file, I see the code-behind depends on the XAML, so I think if I comment out InitializeComponent, then compile with only the XAML, I will have the other part of my code-behind partial class. But this does not work. It doesn't seem to compile the XAML at all unless there is a code behind.
What can I do to reconnect these two files, in most cases?
Edit your project file and make sure you have something similar to this:
<Compile Include="EmployeeGridView.xaml.cs">
<DependentUpon>EmployeeGridView.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
For me the problem was caused by not having the correct way of including the files in the csproj file.
incorrect:
<CodeAnalysisDictionary Include="Windows\ConnectionSecuritySettings.xaml">
correct:
<Page Include="Windows\ConnectionSecuritySettings.xaml">
This happened when I moved the items to a new project
Make sure the declaration at the top of the xaml matches the code behind file with the full path including namespace.
eg. If namespace name is "MyControls" and Code behind Class is "MyNewControl" then
xaml declaration should be something like ..
<UserControl x:Class="MyControls.MyNewControl"
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"
Height="41" Width="77"
>
and code behind would be ..
namespace MyControls
{
/// <summary>
/// Interaction logic for MyNewControl.xaml
/// </summary>
public partial class MyNewControl: UserControl
{
#region Constructors
public MyNewControl()
{
InitializeComponent();
}
#endregion
}
}
I had the same problem (InitializeComponent could not be found) after a cut-paste of my XAML. The answer suggested here solved my problem. The suggestions is, in the Properties window of the XAML, change the Build Action to Page. Apparently the copy-paste can change the Build Action to Resource.
Hope this helps!
[Edit] I just wanted to add that this was also after updating the namespace for both the code-behind and in the xaml:
x:Class="NewNamespace.CodeBehindClass"
I have a class called BIFUserControl which inherits from UserControl class. Now I am designing a new user control called BIFText which inherits from BIFUserControl class. So, I changed the XAML file called BIFText.xaml as follows :
<base:BIFUserControl
xmlns:base="clr-namespace:BaseInputFramework.BaseWidgets;assembly=BaseInputFramework"
x:Class="BIFWidgetLibrary.Text.BIFText"
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"
xmlns:mp="clr-namespace:Microsoft.Multipoint.Sdk.Controls;assembly=Microsoft.Multipoint.Sdk.Controls"
xmlns:utils="clr-namespace:BaseInputFramework.BaseWidgets.Utils;assembly=BaseInputFramework"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="150">
<Grid>
</Grid> </base:BIFUserControl>
And then I changed my BIFText.xaml.cs file as follows:
namespace BIFWidgetLibrary.Text {
public partial class BIFText : BIFUserControl
{
public BIFText()
{
InitializeComponent();
}
} }
But now when I try to build the project, I get the following error message :
'BaseInputFramework.BaseWidgets.BIFUserControl' cannot be the root of a XAML file because it was defined using XAML. Line 2 Position 14.
Can someone please help me with this error. Thanks in advance.
Error says itself that BaseInputFramework.BaseWidgets.BIFUserControl cannot be root of a XAML file since it is defined using XAML. Only elements which are not defined using XAML file can only be root element. Refer to these links - Cannot define root element and Inheriting from UserControl
UserControls work by setting the Content to what you define in XAML, this might be the reason why you cannot inherit like that: The base class' content would be overwritten.
If you don't mind completely replacing the content you might as well use a custom control and define a Template instead.
I'm starting learning XAML and I add some code to my BlankPage application. And suddenly a constructor which is initializing a component:
public BlankPage()
{
this.InitializeComponent();
}
Stop working. I've got now that error:
'BlankApplication.BlankPage' does not contain a definition for 'InitializeComponent' and no extension method 'InitializeComponent' accepting a first argument of type 'BlankApplication.BlankPage' could be found (are you missing a using directive or an assembly reference?)
Honestly I didn't do anything, I didn't even look at this part of code and now it doesn't work.
Screenshot:
Just to give a bit more information on how to fix this (since this explanation is a bit on the vague side)..
This issue (for me) was caused because I changed the namespace in the code after I created the project. In order to fix this issue I had to make some changes in a couple of locations:
1: In App.xaml I had to change the following:
<Application
x:Class="New.Namespace.App"
2: In MainPage.xaml I had to change the following:
<Page
x:Class="New.Namespace.MainPage"
You will also want to make sure that you change the 'namespace' line in your App.xaml.cs as well as your MainPage.xaml.cs.
Finally, you will also want to make sure you update the Project Entrypoint in the Package.appxmanifest to point to "New.Namespace.App".
If your Main class's namespace is different than .xaml file's x:Class attribute, you will get this error. For instance;
Your MainPage.xaml.cs;
namespace UWPControls
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
}
}
Your MainPage.xaml;
<Page
x:Class="UWPControls_Different.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPHelloWorld"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
</page>
You're going to see the error until changing x:class to the;
x:Class="UWPControls.MainPage"
This happens when you change a namespace for a class, you must do the same inside the XAML file.
There are two places inside the XAML file with the old namespace.
For me, the project was inside solution with other projects. When suggestions here did not work, a simple unloading and reloading the project from solution did the trick and fix all errors (with rebuilding of course).
My Solution: For my "SomePage : ContentPage", I changed the XAML properties:
Generator (Custom Tool): From MSBuild:Compile to MSBuild:UpdateDesignTimeXaml
BuildAction: From Page to Embedded resource
Using Visual Studio 2017 Enterprise 15.3.4
Problem solved.
Cause: I forgot to also change custom application name in xaml code.
Solution: I have changed application name in XAML, now it works well.