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
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 would like to create my own user controls which implement more properties and methods than the ones given from .NET Framework. First of all I would like to have a custom UserControl class, which I would call MyUserControl and of course will inherit from UserControl:
public class MyUserControl : UserControl {
public MyUserControl() : base() {
}
...
}
After that I would like to have my own MyTestBox, which will inherit from TextBox.
public class MyTextBox : TextBox {
public MyTextBox() : base() {
}
...
}
My problem now is that I want MyTextBox to inherit from MyUserControl also, because I have properties and methods implemented there, that I need in MyTextBox also.
The only solution I could think of is to make MyTextBox inherit just from MyUserControl and not from TextBox, but add a TextBox in it in the constructor:
public class MyTextBox : MyUserControl {
public MyTextBox() : base() {
Add(new TextBox());
}
...
}
but then I would have to re-implement every single property and method of TextBox in MyTextBox. Is there a better way to achieve this?
Separate out all the common code into a separate class and use delegation to handle it.
ie. something like this:
public class MyUserControl : UserControl
{
private MyExtraControlCode _Extras;
public MyUserControl()
{
_Extras = new MyExtraControlCode(this);
}
public int GetInt32Value()
{
return _Extras.GetInt32Value();
}
}
public class MyTextBox : TextBox
{
private MyExtraControlCode _Extras;
public MyTextBox()
{
_Extras = new MyExtraControlCode(this);
}
public int GetInt32Value()
{
return _Extras.GetInt32Value();
}
}
or something similar.
Not as straightforward, but multiple inheritance is just not supported in .NET.
After looking at the problem in more detail, I finally reached to this conclusion: There are 3 ways to achieve what I want, but all of them require some extra implementation.
First of all multiple inheritance is not supported in C# .NET. In my case it would make things more complex anyway, because in MyTextBox I wanted in a way to be able to access custom properties/methods from both MyUserControl and TextBox. But both of these classes inherit from Component Class, so multiple inheritance (if it were possible) would mess thing up here. The question I asked myself is: What do you finally want to do? The answer is, that I simply want to be able to "extend" all my UserControls (or Components) in general (namely regarding all UserControls) and also specifically (namely regarding TextBox, Combobox, ListView, etc), so that when I create a MyTextBox object, I could do both:
myTextBox.MyUserControlStuff();
and
myTextBox.TextBoxStuff();
So here are my solutions:
1. Use extensions
and extend UserControl (or Component) class. In that case, I have:
public class MyTextBox : TextBox
{
public void MyTextBoxStuff()
{
...
}
}
public static class UserControlExtensions
{
public static void MyUserControlStuff(this UserControl control)
{
...
}
}
And MyTextBox can also do all UserControl stuff and TextBox stuff
Downside: every (specific) extension method applies to UserControl also.
2. Use an interface
public class MyTextBox : TextBox, IUserControlStuff
{
public void MyTextBoxStuff()
{
...
}
public void MyUserControlStuff()
{
...
}
}
public interface IUserControlStuff
{
public void MyUserControlStuff();
}
Downside: I will have to re-implement MyUserControlStuff each time again and again.
3. Use an "extra code" class and make it a member of each custom UserControl & MyUserControl (like #Mr.Karlsen suggested)
See the answer of #Mr.Karlsen for more details. I would say this is the best solution, but it has its downside
Downside: A little messy. A developer, new to my project would find it difficult to understand when seeing it for the first time. I would personally avoid it.
Finally I decided to go with the interface, because my UserControl properties/methods are specific to my needs so it wouldn't be good to extend UserControl with "specific" stuff. I have to write more code in my case and even re-write the same code while implementing my interface's methods, which I really hate. Anyway!!
I have a constructor that is in generated code. I don't want to change the generated code (cause it would get overwritten when I regenerate), but I need to add some functionality to the constructor.
Here is some example code:
// Generated file
public partial class MyGeneratedClass
{
public MyGeneratedClass()
{
Does some generated stuff
}
}
The only solution I can come up with is this:
// My hand made file
public partial class MyGeneratedClass
{
public MyGeneratedClass(bool useOtherConstructor):this()
{
do my added functinallity
}
}
I am fairly sure this will work, but I then have a lame unused param to my constructors and I have to go change them all. Is there a better way? If not that is fine, but I thought I would ask.
If you're using C# 3 and can change the generator, you can use partial methods:
// MyGeneratedClass.Generated.cs
public partial class MyGeneratedClass
{
public MyGeneratedClass()
{
// Does some generated stuff
OnConstructorEnd();
}
partial void OnConstructorEnd();
}
// MyGeneratedClass.cs
public partial class MyGeneratedClass
{
partial void OnConstructorEnd()
{
// Do stuff here
}
}
Would your environment allow you to inherit from MyGeneratedClass rather than have it as a partial class. You could then override the constructor?
Assuming you can't change the generator output, unfortunately, your options are a bit limited, and not ideal considering what you're looking for. They are:
Inherit from the generated class. The child class will implicitly call the parent's construtor.
Use a static method as an initializer