C# 'System.StackOverflowException' in InitializeComponent() - c#

Here are the main parts of the program where the exception seems to be concerned.
using System.Drawing;
using Framework.pages;
namespace Framework
{
public partial class MainWindow : Window
{
public string status;
public MainWindow()
{
InitializeComponent(); // Unhandled exception here
InitializeTheme();
activationStep page = new activationStep();
page.loadPage();
}
// etc etc
This is the abstract class
namespace Framework.pages
{
abstract class template : MainWindow
{
public abstract void loadPage();
public abstract void loadTheme();
}
}
This is the activation step class
using System.Windows.Media;
namespace Framework.pages
{
class activationStep : template
{
public override void loadPage()
{
//this.loadTheme();
}
public override void loadTheme()
{
// Default green activation button
//activateButton.Background = (SolidColorBrush)new BrushConverter().ConvertFromString(Framework.theme.darkGreen);
//activateButton.BorderBrush = (SolidColorBrush)new BrushConverter().ConvertFromString(Framework.theme.borderGreen);
// Set form error color to red
//activationFormError.Foreground = System.Windows.Media.Brushes.Red;
}
// etc etc
The thing is if I comment out these two lines from the MainWindow class:
activationStep page = new activationStep();
page.loadPage();
The program runs fine despite the fact that everything within the activationStep class is commented out anyway (even if they aren't commented out too)? I'm just completely clueless as to why I'm getting this particular exception as there definitely doesn't seem to be any intense loops or anything.
-It's worth noting that there really are not many components loaded into the form and it runs smoothly usually.

You're "newing" up an activationStep, which derives from template, which in turn derives from MainWindow, whose constructor creates a new activationStep... etc, etc.
This loop runs for awhile, and then you get a StackOverflowException.
You'll need to rethink your design.

Related

Changing the startupuri to a derived window class

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

Using another class in WPF C# Project

How to make an object of another class in MainClass.
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
myClass obj = new myClass();
//obj.Show(); //not possible!!
}
public partial class myClass
{
void Show()
{
}
}
}
Now In this project, I can't access Show() method using "obj" object. How do I access method of another Class in this project??
You must declare Show as a public void to have access to the method.
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
obj.Show(); //and must be inside of a method, function or constructor.
}
myClass obj = new myClass();
//obj.Show(); //not possible beacause is not a public method.!!
}
public partial class myClass
{
//public method.
public void Show()
{
}
}
}
After reading your comments I understood that you are new WPF, and confusing some concepts with Console Applications.
In Console Applications, the Main method acts as an entry point, and everything in the method is executed in an orderly fashion from top to bottom, unless some function calls are made. Consider the following example.
Static void Main(string[] args)
{
myClass obj = new myClass();
obj.Show();
}
This code is valid because when the Console Application starts it executes from top to bottom. I mean it creates a myClass object and calls Show method, but in WPF it's different. The only method that executes immediately like Main is MainWindow Constructor. The code after the constructor is not auto executed, unless they are properties, just like a Console Application. I mean the following code will not work properly in a console application.
Static void Main(string[] args)
{
myClass obj = new myClass();
}
obj.Show();
It's because Show method is called out side of the Main method and the program doesn't know what to do with it. Similarly in WPF, you have to call the Show method in the constructor.
public MainWindow()
{
InitializeComponent();
obj.Show();
}
There are many ways to call Show method in WPF, and the above mentioned way is only one of them. The logic Console Applications and Logic of WPF Applications are similar and different at the same time. I suggest you read a few articles or books on WPF to clear things up.

C# - Accessing tree view control from another class

I'm working on a Windows Forms application in C# with Visual Studio 2010.
There is a form mainForm.
mainForm contains a tree view control xmlTreeView.
There is a self-written class myClass.cs.
Now, myClass needs to access the xmlTreeView. However I don't know a) how to access the form and b) which way would be best to do that.
I tried to implement an interface following oleksii's answer but I don't get it. The main form of the application is defined like this:
public interface IMainForm {
TreeView treeView { get; }
}
public partial class mainForm : Form, IMainForm {
public TreeView treeViewControl {
get { return myTreeViewControl; }
}
// Some code here
[...]
RuleTree rt = new RuleTree(); //How do I call this with the IMainForm interface???
}
Another class RuleTree is defined like this:
class RuleTree {
private readonly IMainForm mainForm;
public RuleTree(IMainForm mainForm) {
this.mainForm = mainForm;
}
}
How do I call the constructor of RuleTree with the IMainForm interface???
I would do the following. Don't see it as code, it's just so that you can understand, you can modify it accordingly.
public class MyClass
{
public void MyMethod(YourTreeViewControl treeview)
{
// Do what you need to do here
}
}
Then in your forms code behind just instantiate MyClass and pass an instance of your treeview to it, something like this:
MyClass myClass = new MyClass();
myClass.MyMethod(tvYourTreeViewControl);
Hope this makes sense :)
One of the possible approaches would be to use dependency injection here. MyClass would have a constructor that takes a Form parameter. Thus when you create MyClass it would have the form injected. For example:
Foo
{
Foo(){}
}
Bar
{
private Foo currentFoo;
Bar(Foo foo) //dependency injection
{
currentFoo = foo;
}
public void OtherMethod()
{
//do something with currentFoo
}
}
It will be better to use interfaces (or abstract classes), so instead of Foo you could inject IFoo, this largely decouples your classes, which is a good design decision.
I have commented my code please read comments, I can make solution available as well.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
//Declare a static form that will accesible trhought the appication
//create form called frmMain form or any other name
//
public static frmMain MainForm { get; private set; }
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//comment out default application run
//Application.Run(new MainForm());
//create a new instance of your frmMain form
//inside your main form add a tree view
//Loacte this file "frmMain.Designer.cs"
//Change treeView1 from private to public
// public System.Windows.Forms.TreeView treeView1;
MainForm = new frmMain();
//before I show my form I'll change docking of my tree view from myClass
MyClass mine = new MyClass(); //done
MainForm.ShowDialog();
}
}
public class MyClass
{
public MyClass()
{
Program.MainForm.treeView1.Dock = DockStyle.Fill;
}
}
}
This is not possible to access asp.net server side controls into other class other then their cs class e.g
test.aspx is a page
you can access test page controls only in test.aspx.cs
Other then this class this is not possible.

How to hide public methods from IntelliSense

I want to hide public methods from the IntelliSense member list. I have created an attribute that, when applied to a method, will cause the method to be called when its object is constructed. I've done this to better support partial classes. The problem is that in some environments (such as Silverlight), reflection cannot access private members, even those of child classes. This is a problem since all of the work is done in a base class. I have to make these methods public, but I want them to be hidden from IntelliSense, similar to how the Obsolete attribute works. Frankly, because I am anal about object encapsulation. I've tried different things, but nothing has actually worked. The method still shows up in the member drop-down.
How do I keep public methods from showing up in IntelliSense when I don't want them to be called by clients? How's that for a real question, Philistines! This can also apply to MEF properties that have to be public though sometimes you want to hide them from clients.
Update:
I have matured as a developer since I posted this question. Why I cared so much about hiding interface is beyond me.
Using the EditorBrowsable attribute like so will cause a method not to be shown in IntelliSense:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void MyMethod()
{
}
You are looking for EditorBrowsableAttribute
The following sample demonstrates how to hide a property of a class from IntelliSense by setting the appropriate value for the EditorBrowsableAttribute attribute. Build Class1 in its own assembly.
In Visual Studio, create a new Windows Application solution, and add a reference to the assembly which contains Class1. In the Form1 constructor, declare an instance of Class1, type the name of the instance, and press the period key to activate the IntelliSense drop-down list of Class1 members. The Age property does not appear in the drop-down list.
using System;
using System.ComponentModel;
namespace EditorBrowsableDemo
{
public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
int ageval;
[EditorBrowsable(EditorBrowsableState.Never)]
public int Age
{
get { return ageval; }
set
{
if (!ageval.Equals(value))
{
ageval = value;
}
}
}
}
}
To expand on my comment about partial methods. Try something like this
Foo.part1.cs
partial class Foo
{
public Foo()
{
Initialize();
}
partial void Initialize();
}
Foo.part2.cs
partial class Foo
{
partial void Initialize()
{
InitializePart1();
InitializePart2();
InitializePart3();
}
private void InitializePart1()
{
//logic goes here
}
private void InitializePart2()
{
//logic goes here
}
private void InitializePart3()
{
//logic goes here
}
}

Non-abstract event defined in abstract class won't show in Designer for derived classes

I'm using the class listed below to create a UserControl wrapping a ComboBox that can accept a List<T> and return an object of type T when the internal ComboBox's selection is changed.
Everything works fine in code, exactly as I expect it to, but I can't get SelectedItemChanged event to show up in the Designer anymore when using my control. It worked fine when the abstract base class was non-abstract, but I'm trying to condense 5 essentially duplicate controls into one.
Unimportant parts have been snipped.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
namespace UserComboTest
{
public abstract partial class DropDownList<T> : UserControl where T : class
{
protected abstract int FindIndex(T item);
public abstract void Populate(List<T> items, T defaultItem);
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Browsable(true)]
public event EventHandler<SelectedItemEventArgs> SelectedItemChanged;
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (null != SelectedItemChanged)
{
SelectedItemChanged(this, new SelectedItemEventArgs(Selected));
}
}
public class SelectedItemEventArgs : EventArgs
{
public SelectedItemEventArgs(T selectedItem)
{
Selected = selectedItem;
}
public T Selected { get; private set; }
}
}
public class UserDropDownList : DropDownList<User>
{
protected override int FindIndex(User user)
{
// find index for item
}
public override void Populate(List<User> users, User defaultUser)
{
// populate the list
}
}
}
EDIT: Fixed the code-breaking problem. Turned out both my namespace and form were named UserComboTest, so when it serialized the fully-qualified type name (UserComboTest.UserDropDownList), it assumed that it was a member or class under the form, not the namespace. In other words, it thought it was looking for UserComboTest.UserComboTest.UserDropDownList, which doesn't exist. Renaming the form to UserComboTest.UserComboTestForm solved that half of the problem.
Still remaining is the fact that the designer doesn't show the SelectedItemChanged event, and if I set it manually, it gets removed, so I either have to set it outside of InitializeComponent, or figure out how to get it to be serialized.
Generally, the winforms designer reacts badly to abstract base classes. You should turn the abstract methods into empty virtual methods and make the class non-abstract.

Categories