I have the following setup and I'm wondering if what I'm doing is the best approach:
Project1 //reusable code and controls
mainclass.cs
usercontrol1.xaml
usercontrol2.xaml
Project2 //referencing Project1
mainwindow.xaml //containing usercontrol1.xaml and usercontrol2.xaml
Project1 contains a class and user controls used in other projects, for example Project2.
As the mainwindow in Project2 is initialized I create a new instance of mainclass and pass it as variable to the usercontrols, I also pass the usercontrols as variables to the mainclass.
In this way from the mainclass I can have access to all public methods and variables in the usercontrols and vice versa. Is this a good approach?
public partial class MainWindow : Window
{
public MainClass MC = new MainClass();
public MainWindow()
{
InitializeComponent();
MC.usercontrol1 = this.usercontrol1;
MC.usercontrol2 = this.usercontrol2;
usercontrol1.mainClass = MC;
usercontrol2.mainClass = MC;
}
...
I know that part of this would be more appropriate if done via Events, but the number of methods and variables I need to cross-access between the class and the usercontrols is very high, and doing this way seems to work just fine...
Thanks!
Why not have a constructor in the MainClass since all those classes are in the same project:
public MainClass(usercontrol1 uc1, usercontrol2 uc2)
{
uc1.mainClass = this;
uc2.mainClass = this;
this.usercontrol1 = uc1;
this.usercontrol2 = uc2;
}
then,
public partial class MainWindow : Window
{
public MainClass MC = new MainClass(this.usercontrol1, this.usercontrol2);
public MainWindow()
{
InitializeComponent();
}
...
Otherwise I am not sure what you are trying to do exactly.
Circular dependencies are bad and tightly bound classes are also bad, since they break the open closed principle...
I am not sure what you are trying to accomplish, but I would suggest another class to compose all three classes or else use events if you can.
Related
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
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.
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.
I need to access control of MainPage.xaml.cs from another class. How can I access it?
The question is why? There are a couple of approaches, depending on your architecture:
First thing you can do is to make your MainPage singleton. It makes sense because you only have one Main Page in reality too, but I don't like singletons, and it makes your components coupled and your design becomes hard to unit test.
Alternatively, you can pass an interface of your MainPage into your class. If you only pass the interface, you then have the chance to do unit testing without too much trouble. Something like this:
public interface IMainView
{
void MethodOnMainPage();
}
public class MainPage : IMainView
{
}
public class MyClass
{
private IMainView _view;
public MyClass(IMainView view)
{
_view = view;
}
private void SomeEventHappened()
{
_view.MethodOnMainPage();
}
}
Why can't I access the tabcontrol from within myclass.cs?
The tabcontrol is in form1.cs and my code that tries to create a new tabpage is in myclass.cs. I've even tried setting tabcontrol property to public but that didn't work.
just change the modifier on the control to public.
Once you do that and you have Form myForm = new Form();
you will be able to do:
myForm.myTAB.TabPages.Add(myTabPage);
(You will need to create the TabPage of course.
I'd suggest to wrap the TabControl in an public readonly property on the form's codebehind file, rather than making the control itself public. Just for the sake of code security (like being able to reassign your TabControl to something new).
public TabControl MyTabControl {
get {
return privateTabControl;
}
}
Also, don't forget you'll need an instance to your form in MyClass, otherwise you can't access instance members like "MyTabControl" or even public instance fields if you've chosen so.
I suggest you embed a reference to the TabControl on the Form in the Class myclass.cs.
You could do this either by defining a constructor for myclass that took a TabControl as a parameter, or, by defining a Public Property in myClass that holds a reference to a TabControl. Both ways are illustrated here :
public class myclass
{
// using "automatic" properties : requires C# 3.0
public TabControl theTabControl { get; set; }
// parameter-less 'ctor
public myclass()
{
}
// optional 'ctor where you pass in a reference to the TabControl
public myclass(TabControl tbControl)
{
theTabControl = tbControl;
}
// an example method that would add a new TabPage to the TabControl
public void addNewTabPage(string Title)
{
theTabControl.TabPages.Add(new TabPage(Title));
}
}
So you can set the TabControl reference in two ways from within the Form with the TabControl :
myclass myclassInstance = new myClass(this.tabControl1);
or
myclass myclassInstance = new myClass();
// do some stuff
// now set the TabControl
myClassInstance.theTabControl = this.tabControl1;
An alternative is to expose a Public Property of type TabControl on Form1 : but then you have to think about how myclass will "see" the current "instance" of Form1 ... if there is more than one instance of Form1 ? In the case there is one-and-only-one TabControl you could use a static Property on Form1 to expose it.
In this case "who is creating who" becomes of interest : if the Form is creating myclass; if myclass is creating the Form; if both myclass and the Form are being created by another entity in the application : I think all these "vectors" will bear on what is the best technique to apply.
Are you creating an instance of form1 in myclass.cs and checking the existence of tabControl on that instance? If you want to access form1.tabControl in myclass.cs then you will need to make the tabControl as public static in form1.cs
This might be an overly simple suggestion, and you've probably solved this by now, but did you remember to include using System.Windows.Forms at the top of the class file? Visual Studio may not include that reference automatically when adding a new class file.