Partial nested Form class with designer - c#

I am making a MessageBox like class (MessageBoxCustom).
I would like to have a Form with designer support in a separate file so I can modify the appearance through Visual Studio (MessageBoxCustomDialog ).
I would also like to make this MessageBoxCustomDialog unreachable by code outside MyMessageBox and I'm nesting MessageBoxCustomDialog. I would like to move it in a separate file so I'd have designer support. Maybe using a partial class? How would the hierarchy go?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace System.Windows.Forms
{
public static class MessageBoxCustom
{
public static void Show()
{
(new MessageBoxCustomDialog()).ShowDialog();
}
private class MessageBoxCustomDialog : Form
{
}
}
}

The Visual Studio Designer can not help you design nested classes. It is just not made for that. It checks the type of the first outermost class in the file and then decides which designer to use.
If it is just about designing the layout of the form I would recommend to design it as usual. When you finished your project you can then surround the class by the outer class (in both files) and make it private.
When you finshed your work just copy and paste the dialog class into the outer class and make it private. If you have to rework the design it is again just copy and paste.
MessageBoxCustomDialog.cs:
namespace System.Windows.Forms
{
// make sure this is the first class in the file (required by designer)
public partial class MessageBoxCustomDialog : Form
{
public MessageBoxCustomDialog()
{
InitializeComponent();
}
}
public static partial class MessageBoxCustom
{
public static void Show()
{
new MessageBoxCustomDialog().ShowDialog();
}
// put the MessageBoxCustomDialog class here when you are done
}
}
MessageBoxCustomDialog.Designer.cs:
namespace System.Windows.Forms
{
partial class MessageBoxCustomDialog
{
...
}
partial class MessageBoxCustom
{
// put the MessageBoxCustomDialog class here when you are done
}
}

Make your MessageBoxCustomDialog a private partial inner class
private partial class MessageBoxCustomDialog : Form
{}

You must make MessageBoxCustom partial having same scope of MessageBoxCustomDialog
File 1
using System.Windows.Forms;
namespace System.Windows.Forms
{
public static partial class MessageBoxCustom
{
public static void Show()
{
(new MessageBoxCustomDialog()).ShowDialog();
}
private partial class MessageBoxCustomDialog : Form
{
}
}
}
File 2
using System.Windows.Forms;
namespace System.Windows.Forms
{
public static partial class MessageBoxCustom
{
private partial class MessageBoxCustomDialog : Form
{
// designer code
}
}
}
You may see this link http://msdn.microsoft.com/en-us/library/wa80x488.aspx [Restrictions section]

Related

Call method in partial class

I'm using Visual Studios. I wrote a method in a form1.cs file in a partial class
private void TestMethod1()
{
}
I want to call this method in form2.designer.cs, in the same partial class. I tried this:
TestMethod1();
but I got the error method not found.
this is the form.cs
namespace classA
{
public partial class A : B
{....
private void TestMethod1()
{
}
}
}
this is the form.designer.cs
namespace classA
{
partial class A
{
private void InitializaCOmponent()
{
.....
}
(where I call my function)
TestMethod1();
}
}
If the situation is as you described, then the compiler should not generate the error message as it is valid code.
However, if you try to use the visual editor, and you insert the call in your code inside the InitializeComponent method you will get an error.
This is caused by the Form editor not being able to call functions that are defined within the class you are actually editing - it is a bit restrictive about what you can do within that scope.

How to deal with imported class and use them in Parent Class

How do i rename an imported class so i can access it.Below is the code of the Class with a different name space which was imported and the Class of the one i am working on respectively.Should i just change the name space?
namespace FaultTreeSelectionAsistant
{
public partial class Astra : Form
{
public Astra()
{
InitializeComponent();
}
}
}
namespace THE_HELP
{
public partial class MainPanel : Form
{
public MainPanel()
{
InitializeComponent();
}
private void MainPanel_Load(object sender, EventArgs e)
{
}
}
}
You can give an alias to a namespace or a class like this :
using FTSA = FaultTreeSelectionAsistant;
using FtsaAstra = FaultTreeSelectionAsistant.Astra;
Use . (dot) to delimit namespaces in a declaration :
In MainPanel, you can declare:
FaultTreeSelectionAsistant.Astra astra;
To avoid expliciting the namespace name, you can import it with a using declarative:
using FaultTreeSelectionAsistant;
Please consult MSDN for a complet description of what are namespaces and how to use them.
Simplest way is to use intellisense:
Just write the class name for example Astra, mouse hover and see the option:

Nested class written outside of the class

I like using private nested classes, except that they always feel so cluttered. Normally I put them in their own #region, but I would prefer them to be separate from their parent class in terms of location, and I also don't really want them in separate files. What I decided to do was to make their parent class partial, and then to place the child class physically below the parent class in the file.
Unfortunately it seems that you can't have more than one partial class definition per file either.
(EDIT: it turns out you can have more than one partial part per file; it's just the forms designer that doesn't like it.)
What I would really like to do is something like (all in one file):
internal class Parent
{
}
private class Parent.Child1
{
}
private class Parent.Child2
{
}
but it seems like all I can do is either generate a new source file for every new child class, or arrange them like this:
internal class Parent
{
private class Child1
{
}
private class Child2
{
}
}
Is there any way to accomplish what I'm trying to do here?
The closest you can get to this type of encapsulation is using a partial parent class:
internal partial class Parent
{
private Child1 c1Instance = new Child1();
private Child2 c2Instance = new Child2();
}
internal partial class Parent
{
private class Child1
{
}
}
internal partial class Parent
{
private class Child2
{
}
}
You can split these up into multiple files, the end result will be the same - Child1 and Child2 will be private classes internal to Parent and inaccessible elsewhere.
Makes it a bit more confusing sometimes, but I think it's the closest thing to what you are trying to achieve.
Clarification
A C# source file can hold any number of namespaces, and each namespace can contain any number of structs and classes.
This is a valid (but not very functional) C# source file:
using System;
namespace FirstNS
{
public class Class1
{
}
public class Class2
{
}
public partial class Parent1
{
}
public partial class Parent1
{
private class Child1
{
}
private class Child2
{
}
}
}
namespace FirstNS.ChildNS
{
public class Class3
{
}
}
Compiling that gives you the following classes:
FirstNS.Class1
FirstNS.Class2
FirstNS.Parent1
FirstNS.Parent1.Child1 (private)
FirstNS.Parent1.Child2 (private)
FirstNS.ChildNS.Class3
You could also split each of the class definitions above into multiple files, if you have a reason to do so.

add partial file to existing form file

I have a Window Form App project. At the moment all of my code is in Form1.cs file which is the default file. Now I have about 1300 lines of code in this single file. I want to break down this one file code into several files and I want to use the "partial" key word (I don't want to do anything drastic). So how should I add the files
Right click project name->add->new item ->class results into class1.cs, class2.cs and so on
But this file converts to a form form file after compilation. What's the correct way of adding so that the new file integrates with my existing project Form1.cs and Form1.cs[Design]?
You have to keep the namespace, the class name and mark it with partial. The file name is not really important for it to work, but it's a good practice so that the developers can identify rapidly the contents of the file.
Form1.cs
namespace TheSameNamespace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
// other definitions
}
Form1.Designer.cs
namespace TheSameNamespace
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
// the rest of the designer class
}
}
Form1.Calculations.cs
namespace TheSameNamespace
{
partial class Form1
{
// calculation methods definitions
}
}
Form1.EventHandlers.cs
namespace TheSameNamespace
{
partial class Form1
{
// event handlers definitions
}
}
and so on...
The partial keyword is primarly for generated files, which can be extended by your own code - there is no use in splitting a single bloated class into multiple partials, but if you really want to do it then you have to:
Create a new class.
Rename the class to match your own class (Form1.xxx.cs)
Use the partial key-word and adjust the name and the namespace.
To clearify:
Form1.cs
public partial class Form1 { /* ... */ }
Form1.somepart.cs
public partial class Form1 { /* ... */ }

Override a UseControl's library

I would like to develope a WPF User Control Library that uses a Class Library with a member function that can be over-ridden . I’m using C# 4.0 and VS 2010.
My test class library looks like:
using System.Diagnostics;
namespace MyLibrary {
public class Foo {
virtual public void Bar() {
Debug.WriteLine(" Hi from MyLibrary, class Foo, method Bar.");
}
}
}
My WPF User Control looks like:
using System.Windows.Controls;
using System.Diagnostics;
using MyLibrary;
namespace MyUserControl {
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
Debug.WriteLine("MyUserControl: ");
var foo = new Foo();
foo.Bar();
}
}
}
I have built a WPF Application called ProgramA, and it looks like:
using System;
using System.Diagnostics;
using System.Windows;
namespace ProgramA {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
}
}
When debugging ProgramA, you will see:
MyUserControl:
Hi from MyLibrary, class Foo, method Bar.
in the debug Output window. So far, so good.
I have also built ProgramB to try to override the Bar method of MyLibrary.
ProgramB looks like:
using System.Windows;
namespace ProgramB {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
}
}
The XML for both ProgramA and ProgramB contains a reference to MyUserControl:
<Window x:Class="ProgramB.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:my="clr-namespace:MyUserControl;assembly=MyUserControl">
<Grid>
<my:UserControl1 Name="userControl11"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Grid>
</Window>
I have added a Class to ProgramB's project called NewFoo.cs, and it looks like:
using System.Diagnostics;
using MyLibrary;
namespace ProgramB {
class NewFoo : MyLibrary.Foo{
override public void Bar() {
Debug.WriteLine(" Hi from ProgramB Foo, method Bar.");
}
}
}
ProgramB compiles and runs, but the output is:
MyUserControl:
Hi from library Foo, method Bar.
The override did not work.
Here is the problem. The Namespace for ProgramB’s Foo method is ProgramB, and hence it does not override the Bar method of MyLibrary.
Is there a way ProgramB can override the Bar method used by MyUserControl?
Any help or suggestions will be greatly appreciated.
Charles
Its because UserControl1 doesnt know about NewFoo and only instantiates Foo. It has nothing to do with namespaces.
The override will work, as long as you provide the correct instance.
You should expose a property in UserControl1 where you can set what foo to use.

Categories

Resources