Different base class in the XAML file - c#

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.

Related

"Kproj.Forms.frmSwitch" cannot be the root of a XAML file because it was defined using XAML

I am aware that there are other questions posted that appear to be the same issue but none of them fix my issue.
I'm new to WPF I'm trying to convert a program from WinForms to WPF. I have a main window, "Kproj.Forms.frmLogin", that inherits a base class, "Kproj.Forms.frmSwitch", that inherits the System.Windows.Window class. WhenI got the above issue, my initial XAML code was:
<Control:frmSwitch x:Class="Kproj.Forms.frmLogin"
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:Control="clr-namespace:Kproj.Forms"
mc:Ignorable="d"
Title="LOG IN" Height="309" Width="678">
<Grid Height="271" Width="662">
... Content
</Grid>
</Control:frmSwitch>
with these in the code-behinds:
namespace Kproj.Forms
{
public partial class frmLogin : frmSwitch
{
}
}
namespace Kproj.Forms
{
public partial class frmSwitch : Window
{
}
}
Upon further research, I found out that I needed to make frmSwitch into a base class with no XAML. Thus, I created frmSwitch2 in just general Class form that looks like this:
namespace Kproj.Forms
{
public class frmSwitch2 : Window
{
}
}
I then adjusted the main window XAML accordingly:
<Control:frmSwitch2 x:Class="Kproj.Forms.frmLogin"
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:Control="clr-namespace:Kproj.Forms"
mc:Ignorable="d"
Title="LOG IN" Height="309" Width="678">
<Grid Height="271" Width="662">
... Content
</Grid>
</Control:frmSwitch2>
and the main window code-behind to:
namespace Kproj.Forms
{
public partial class frmLogin : frmSwitch
{
}
}
Now, I lost the original error message, but I gained a message that states
"The name 'frmSwitch2' does not exist in the namespace 'clr-namespace:FITS.Forms'."
even though it suggests "frmSwitch2" when I type "Control:" in the main window XAML, so it knows it does exist in the namespace. Any suggestions?
Disclaimer: I tried researching it as best as possible but all the posts I found on StackOverflow were this issue but all were fixed by converting from XAML\cs partial classes to solo code-behind full XAML-less class.
After looking into what the inheritance actually wanted, I learned that the only purpose of the inheritance was for variables so I was able to make it work but just converting them to static global variables and accessing them directly. I ended up not needing the inheritance after all.
If anyone else, that ends up knowing more MVVM, does come across a fix for this issue, it would be nice to know it. Even though I no longer need it, it would be good learning.

How do I reconnect a XAML view file with it's code behind file?

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"

WPF Resource Dictionary using code behind file can’t be found

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();
}
}
}

Add control to custom base page

I'm trying to create a custom base page for my WP app. I'm doing this by creating a new cs class file that inherits from PhoneApplicationPage like this:
public class BasePage: PhoneApplicationPage
{
//handle common non-visual stuff here
}
The problem is that I would like to add a control on every page that uses BasePage but BasePage has no LayoutRoot or any visual element that I can attach the control to. Is there a way I can add the same control to all the pages that use BasePage so that I don't have to copy/paste it every time?
Edit: Adding XAML based on TriggerPin's answer. I've created a new XAML file for my BasePage.cs but this is throwing errors in BasePage.g.cs:
"MyApp.MainPage already contains a definition for '_contentLoaded'" (and similar message for 'LayoutRoot' and 'InitializeComponent')
<local:BasePage
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:local="clr-namespace:MyApp.Template"
x:Class="MyApp.MainPage"
mc:Ignorable="d">
Notice that by default, types derived from PhoneApplicationPage are partial
public partial class MainPage : PhoneApplicationPage
The partial definition allows you to split the class definition across multiple files. Most commonly with this type, the definition is split between a .cs and .xaml file.
<phone:PhoneApplicationPage x:Class="MyProject.MainPage"
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">
<!-- Custom layout here -->
</phone:PhoneApplicationPage>
If you make your implementation a partial class and provide base xaml code, you will be able to do what you want to achieve.
You need a container which must be Panel type at least for adding your children controls. A Page is just a UserControl which couldn't add your UIElement into it directly.
Try this:
Panel container = // init it from your page, you must have a root element in page.
container.Children.Add(new TextBlock()); // your children control.
I did it in Win8.

Changing from WPF User Control to Window?

I've been working on a commandline application, and have recently decided to add a wpf window to the application. I added this as a UserControl, however I noticed I can't call this class using ShowDialog() from my main code;
I've tried changing the Base class from a UserControl to Window, however an error occurs;
public partial class UserControl1 : Window
{
public UserControl1()
{
InitializeComponent();
}
Error 1 Partial declarations of
'ExcelExample.UserControl1' must not
specify different base
classesExcelExample
I've added all the references found in my other WPF application to no avail. Help!
In order to change the base class it is not sufficient to change it in code only. You must also change the root tag and any nested elements in accompanying XAML file. For example, you have something like:
<UserControl x:Class="Your.Namespace.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
</UserControl.Resources>
</UserControl>
You must change it to something like:
<Window x:Class="Your.Namespace.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
</Window.Resources>
</Window>

Categories

Resources