I'm having trouble with naming my Window which is inherited from its Base Window,
when I try to give a name to my Window I get following error.
The type BaseWindow cannot have a Name attribute. Values types and types without a default constructor can be used as items within ResourceDictionary.
XAML :
<log:BaseWindow
x:Class="EtraabMessenger.MainWindow"
x:Name="main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:log="clr-namespace:EtraabMessenger.MVVM.View.Controls"
xmlns:VMCore="clr-namespace:EtraabMessenger.MVVM.VMCore"
VMCore:WindowClosingBehavior.Closing="{Binding DoCloseMainWindowCommand}"
Height="464" Width="279">
</log:BaseWindow>
EDIT : Here is my BaseWindow class
public abstract class BaseWindow : Window, INotifyPropertyChanged
{
protected BaseWindow()
{
// Note (Important) : This message should register on all windows
// TODO : I'm planning to move this registeration to BaseWindow class
Messenger.Register<bool>(GeneralToken.ClientDisconnected, DisconnectFromServer);
}
protected abstract void DisconnectFromServer(bool isDisconnected);
protected abstract void RegisterTokens();
protected abstract void UnRegisterTokens();
....
....
....
}
Any advice will be helpful.
Your base window apparently, as the error states, needs a public default contructor (one without arguments), it also may not be abstract because an instance of it needs to be created.
Related
Let's say in a WPF project I've built an abstract window class so I can add some base properties to every window I create derived from that:
// Abstract window, based on normal window
public abstract partial class abs_window : Window
{
// example of added property to my abstract class
protected int xxx = 25;
public abs_window()
{
InitializeComponent();
}
}
// Another class dervied from my abstract window
public partial class derivedWindow : abs_window
{
void aa()
{
// Random method aa() to show access to the protected xxx int
MessageBox.Show(Convert.ToString(xxx));
}
}
So, this compiles fine, but my StartUpUri is pointing to the default MainWindow that I don't really want at all... I want it to point straight to a new instance of my doubly derived derivedWindow class? Is that possible?
I tried both
StartupUri="abs_window.xaml" and StartupUri="derivedWindow.xaml"> but the first couldn't work since it's abstract and the 2nd doesn't work because there isn't an existing .xaml file
If I add a new "window" .xaml file it'll just be a normal window and not my derived type!?
Answering on behalf of Hans' comment unless he chooses to answer also:
First created a startup method in the default App class (App.xaml.cs) like Hans' link here
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
derivedWindow window = new derivedWindow();
window.Show();
}
}
But what that link didn't mention was to change the App.xaml file by replacing a StartupUri which seems to be always referencing an .xaml with a Startup method StartupUri="MainWindow" with Startup="App_Startup" which I found here
I'm trying to add a few extra base properties (somewhere) in my project so that every window I create will automatically inherit these properties.
E.g. each window will have a "block_count" based on the area of the window
For context, I'm using a WPF project.
Currently trying: I've created an abstract window class with my desired properties and then defined my MainWindow as one of these types to inherit the property and method...
But when coding in my MainWindow class I still can't access the property or method even though it should have inherited them? Where am I going wrong or what is the best way to add properties to all windows in my project?
My Abstract Window class
public abstract partial class AbWinDefiner : Window
{
private int _block_count;
private void get_block_count()
{
_block_count = Convert.ToInt32(Math.Floor(Width * Height / 32));
}
public AbWinDefiner()
{
InitializeComponent();
}
}
My Main Window class
public partial class MainWindow : AbWinDefiner
{
public MainWindow()
{
InitializeComponent();
}
}
Make it protected, not private
I am trying to add a web browser to an existing C# application, but, having not used C# in about 6 years, I am quite unfamiliar with how it works.
I am trying to add the browser to a partial class (again, something I am not familiar with) using the following code:
public partial class WebBrowser : WebBrowserBase{
public WebBrowser(){
...
}
...
}
However, I am getting a compile error on the constructor that says:
'WebBrowserBase' does not contain a constructor that takes 0 arguments
I Google'd this, and came across the following question on SO: C# Error: Parent does not contain a constructor that takes 0 arguments. I tried doing what was suggested in the answer to this, and changed my code to:
public partial class WebBrowser : WebBrowserBase{
public WebBrowser(int i) : base(i){
...
}
...
}
However, I then get a compile error that says:
'WebBrowserBase' does not contain a constructor that takes 1 arguments
So I'm guessing that this issue isn't to do with the number of arguments in the constructor... Can anyone explain what I'm doing wrong here?
If you have a look at WebBrowserBase Class it states that:
"This API supports the product infrastructure and is not intended to be used directly from your code."
And it seems that it doesn't have any public constructor - so you can't inherit from it. But if you don't want to create your own WebBrowser control (alter some of it's functionality), you should just use the default System.Windows.Forms.WebBrowser in a XAML View:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<WebBrowser HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Window>
In Inheritance,
If Derived class contains its own constructor which not defined in Base class then this error Occurs
For Example:
class FirstClass
{
public FirstClass(string s) { Console.WriteLine(s); }
}
class SecondClass : FirstClass
{
public SecondClass()
{
Console.WriteLine("second class");
}
}
Output: Error:-'myconsole.FirstClass' does not contain a constructor that takes 0 arguments
To Run without Error:
class FirstClass
{
public FirstClass()
{
Console.WriteLine("second class");
}
public FirstClass(string s) { Console.WriteLine(s); }
}
class SecondClass : FirstClass
{
public SecondClass()
{
Console.WriteLine("second class");
}
}
I am having trouble calling base constructors in wpf windows:
public class TemplateWindow : Window //Template window class
{
public TemplateWindow (int no)
{
}
}
public partial class MainView : TemplateWindow
{
public MainView() : base(1) //error here
{
InitializeComponent();
}
}
It gives me an error at the indicated location as it apparently is trying to call the Window constructor with base instead. The MainView class is the code behind of a xaml window.
However, when I tested the problem like below, it works perfectly fine.
class A //Base Class
{
public A() { }
}
class B : A
{
public B(int no) { }
}
partial class C : B
{
public C() : base(1) { }
}
What am i doing wrong?
You have your MainView class defined in XAML, don't you? It probably goes something like this:
<Window x:Class="MyNamespace.MainView" ... >
...
</Window>
Note the big Window word right at the beginning. It tells the compiler that you want this XAML to generate a class named MyNamespace.MainView, and you want it to inherit from Window. So that's what the compiler does: it happily generates your class and makes it inherit from Window. Right-click the InitializeComponent word and choose "Go to Definition". This will take you to the autogenerated file, and you'll be able to see the class.
Now, if you want MainView to inherit from TemplateWindow, you just have to say so in your XAML:
<my:TemplateWindow
xmlns:my="MyNamespace"
x:Class="MyNamespace.MainView" ... >
...
</my:TemplateWindow>
But that will give you another problem: now, all of a sudden, you can't use the visual designer.
That would be because the designer cannot create an instance of your TemplateWindow class for editing. Why? Well, because TemplateWindow doesn't have a default constructor, of course!
So for this kind of thing to work, you'll just have to define two constructors in TemplateWindow - one default, and one accepting an int.
Good luck.
Here is your answer
http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx
The following WPF UserControl called DataTypeWholeNumber which works.
Now I want to make a UserControl called DataTypeDateTime and DataTypeEmail, etc.
Many of the Dependency Properties will be shared by all these controls and therefore I want to put their common methods into a BaseDataType and have each of these UserControls inherit from this base type.
However, when I do that, I get the error: Partial Declaration may not have different base classes.
So how can I implement inheritance with UserControls so shared functionality is all in the base class?
using System.Windows;
using System.Windows.Controls;
namespace TestDependencyProperty827.DataTypes
{
public partial class DataTypeWholeNumber : BaseDataType
{
public DataTypeWholeNumber()
{
InitializeComponent();
DataContext = this;
//defaults
TheWidth = 200;
}
public string TheLabel
{
get
{
return (string)GetValue(TheLabelProperty);
}
set
{
SetValue(TheLabelProperty, value);
}
}
public static readonly DependencyProperty TheLabelProperty =
DependencyProperty.Register("TheLabel", typeof(string), typeof(BaseDataType),
new FrameworkPropertyMetadata());
public string TheContent
{
get
{
return (string)GetValue(TheContentProperty);
}
set
{
SetValue(TheContentProperty, value);
}
}
public static readonly DependencyProperty TheContentProperty =
DependencyProperty.Register("TheContent", typeof(string), typeof(BaseDataType),
new FrameworkPropertyMetadata());
public int TheWidth
{
get
{
return (int)GetValue(TheWidthProperty);
}
set
{
SetValue(TheWidthProperty, value);
}
}
public static readonly DependencyProperty TheWidthProperty =
DependencyProperty.Register("TheWidth", typeof(int), typeof(DataTypeWholeNumber),
new FrameworkPropertyMetadata());
}
}
Ensure that you have changed the first tag in the xaml to also inherit from your new basetype
So
<UserControl x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
>
becomes
<myTypes:BaseDataType x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:myTypes="clr-namespace:TestDependencyProperty827.DataTypes"
>
So, to summarise the complete answer including the extra details from the comments below:
The base class should not include a xaml file. Define it in a single (non-partial) cs file and define it to inherit directly from Usercontrol.
Ensure that the subclass inherits from the base class both in the cs code-behind file and in the first tag of the xaml (as shown above).
public partial class MooringConfigurator : MooringLineConfigurator
{
public MooringConfigurator()
{
InitializeComponent();
}
}
<dst:MooringLineConfigurator x:Class="Wave.Dashboards.Instruments.ConfiguratorViews.DST.MooringConfigurator"
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:dst="clr-namespace:Wave.Dashboards.Instruments.ConfiguratorViews.DST"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
</Grid>
</dst:MooringLineConfigurator>
I found the answer in this article: http://www.paulstovell.com/xmlnsdefinition
Basically what is says is that you should define an XML namespace in the AssemlyInfo.cs file, which can the be used in the XAML. It worked for me, however I placed the base user control class in a separate DLL...
There is partial class definition created by designer, you can open it easy way via InitializeComponent() method definition.
Then just change partial class iheritence from UserControl to BaseDataType (or any you specified in class definition).
After that you will have warning that InitializeComponent() method is hidden in child class.
Therefore you can make a CustomControl as base clas instead of UserControl to avoid partial definition in base class (as described in one comment).
I ran into the same issue but needed to have the control inherit from an abstract class, which is not supported by the designer. What solved my problem is making the usercontrol inherit from both a standard class (that inherits UserControl) and an interface. This way the designer is working.
//the xaml
<local:EcranFiche x:Class="VLEva.SIFEval.Ecrans.UC_BatimentAgricole"
xmlns:local="clr-namespace:VLEva.SIFEval.Ecrans"
...>
...
</local:EcranFiche>
// the usercontrol code behind
public partial class UC_BatimentAgricole : EcranFiche, IEcranFiche
{
...
}
// the interface
public interface IEcranFiche
{
...
}
// base class containing common implemented methods
public class EcranFiche : UserControl
{
... (ex: common interface implementation)
}