windows application - c#

Am doing one project in C# windows application with MVC pattern. In that i need to access the controls from client Form to ClientStatus Form any ideas

Your forms fall under the V (view) part of MVC; they only need to present data to the user and provide means for interaction. They don't need to know about what other forms are doing because that is handled in the controller...
Logic to react to user interaction should be contained in the C (controller) part. So in your example the controller will respond to user input on one form to update the state of the other form.
In basic terms your controller should instantiate the forms, react to events on the interactive form, and call methods or modify properties on the other form to update it. The method you use to achieve this depends on the technology you are using; if you are using WinForms then use events and delegates. If you are using WPF then you should look into data binding.

If you are actually using MVC your Forms shouldn't need each other controls. Your forms shouldn't even know each other.
Please explain your situation better.

Since you post no code explaining your implementation of MVC in WinForms, I'm not sure how you're actually instantiating and showing the Forms. I'll assume that you're still calling constructors somewhere in your own code though.
Pass a reference to the Client Form when the ClientStatus form is created (and create a constructor on the ClientStatus form to accept the Client Form as a parameter):
public class ClientForm : Form
{
public ClientForm() { }
}
public class ClientStatusForm : Form
{
ClientForm _parent;
public ClientStatusForm(ClientForm parent)
{
_parent = parent;
}
}

Related

How can I pass informations between the form and the user controls?

I have a problem with my project. Since I do not like it that every Windows Form is a new window I did try to use an different way.
This way I did create an FormGUI which contains the menu and calls the different UserControls. Since we did only learn how to use Windows Forms I do know how to work with them. There I would have changed the constructor of the new Windows Form to pass Data.
But this time I use mainly one Windows Form and different UserControls.
e.g. I have one to add new data, an other one to show data in a datagrid and one to show the data inside of an chart. At least this is the result.
But I do not finde a way to transport informations from the Windows Form into one User Control and how to get them back. In order to use this knowlegde somewhere else.
Does someone knew a tutorial where I can see how it could work? Or could explain it to me.
Since the UI is part of the end project that will be marked I would prefer my new way. But if I can't find a work around I will need to change it so that I would work with different windows form. >_> But really... I do not want the application to open new windows for every task. I would prefer to only show the information in one page.
In my search I did found some tutorials about UI Design with Windows Form but only the design (where a chart would be placed it is only a picture) an not how this will work with real informations.
I hope you could understand my problem...
Let's assume that the constructor of the form is something like this
private List<MyData> _data;
public MyForm(List<MyData> data)
(
...
_data = data;
)
Declare an interface
public IDataAware
{
List<MyData> Data { get; set; }
}
and let the user controls implement it. E.g.
public MyDataGridUserControl : UserControl
{
...
public List<MyData> Data {
get { return (List<MyData>)dataGridView1.DataSource; }
set { dataGridView1.DataSource = value }
}
}
If you are working with a BindingSource, access the BindingSource instead of the grid control. Now, you can access all your user controls through the same interface. In the form you can create a field
private IDataAware _dataUserControl;
In a menu item click routine, you could do some thing like this
_dataUserControl = new MyDataGridUserControl();
in another one
_dataUserControl = new MyChartUserControl();
But all the user controls implementing IDataAware you can do
Controls.Add(_dataUserControl);
_dataUserControl.Data = _data;
Note: Forms, Controls and UserControls are just classes as any other class, and you can do all the object-oriented things with them as with any c# class. (There are some restrictions with generics, however.)

Winforms Inhereted Control preventing the designer from working

I have 2 forms that inherit a control from the class below:
public class AInbox: Form
{
public FlowLayoutPanel InboxItems;
}
The forms inherits as such:
public partial class Inbox : AInbox
{
...
}
In the Designer.cs file i commented out the original "InboxItems" control declaration and everything compiles and runs fine... except the GUI designer. When i open the Designer I get the error "The variable 'InboxItems' is either undeclared or was never assigned."
Is there any way to use this inheritance and still have the designer work?
I'd recommend against inheriting a form with generated code (like you're doing with Inbox).
If you want the child class (Inbox) to add additional controls, I wouldn't use the designer directly on the child class, because I don't think the visual studio form designer will play nicely when half of the form was designed in the parent class. If you need to reuse certain parts of your form in a different form, you might want to consider moving that part of the form to a separate user control. You can use the designer on this user control and later put the user control in the forms.
If you just need to have the same form, keep an instance of the form in your other class. Move your logic away from your form (view) and in your other class (controller).

WPF, MVVM, and effective navigation / control flow

I am currently building an application based on a real world scenario, to help me learn and understand WPF and MVVM. To that end I have read and worked through Karl Shifflett's "In The Box" VSIX, and I was able to adapt most of the concepts to the application that I am working on.
While I think MVVM is a powerful design pattern, it does (seemingly) make things that were once trivial (e.g. displaying messages, navigation, interacting with multiple window), not so trivial or straightforward. Now onto the crux of my problem / confusion.
The WPF application that I am working on is a Windows based application, and I am working from a set of basic requirements:
A basic login screen
After a successful login, close the login screen and open the actual application
Simulate a typical program workflow (opening "child" windows via button clicks, displaying modal windows, etc.)
Preform data validation / error handling
Log out
I am used to working with MDI Applications on a windows platform where interactions on a parent form cause child forms to open; I understand that MDI is not something that WPF supports and I am fine with approaching development from a different perspective. My UI would still work in a similar manner to a MDI application though: I have my application layout, and as I interact with that layout my application will respond by opening windows, displaying messages, and so on. It isn't clear to me (via MVVM) how to interact with multiple windows, or how well MVVM would scale to a large application with many windows / views.
I am not opposed to using something like Prism, but I haven't found a good article on how Prism approaches my particular problem very well. Any help, advice, feedback, or otherwise is greatly appreciated!
Have you tried looking at nRoute Framework?
A link can be found here
There are actually some good tuturials about prism
Link 1
Link 2 (Part II of Link1)
Link 3
For a more straight forrward application (not very complex and modular), you can always create a aplication, with a main window that manages child usercontrols (login window, menu window, other windows ...)
For example, create a window a contentpresenter in it, and in codebehind:
public partial class ShellWindow: Window
{
public enum PagesTypes { Login, Home }
PagesTypes currentOpenedPage;
LoginUserControl login;
HomeUserControl home;
public WindowController()
{
InitializeComponent();
login = new LoginUserControl ();
login.GoToPage += new LoginUserControl.ChangePageHandler(GoToPage);
GoToPage(PagesTypes.Login);
}
public void GoToPage(PagesTypes page)
{
switch (page)
{
case PagesTypes.Login:
//Close last opened usercontrol,
....
//open new usercontrol
login = new LoginUserControl();
contentpresenter.content = login;
break;
//other pages cases
....
}
currentOpenedPage = page;
}
}
And in for example the login usercontrol:
public partial class LoginUserControl : UserControl
{
internal delegate void ChangePageHandler(ShellWindow.PagesTypes toPage);
internal event ChangePageHandler GoToPage;
public LoginUserControl()
{...}
//Methods for login
.....
internal void LoginOK()
{
if(this.GoToPage != null)
GoToPage(ShellWindow.PagesTypes.Home);
}
}
You can build a good dynamic using this method changing usercontrols, simulating diferent windows.
Hope this gives you some ideas.
MVVMing your child windows actually can be kind of easy, especially if you decide that a tabbed interface is OK. Your outer window's view model simply has a collection of ChildWindowViewModel. You create a new tab just by creating the new view model, asking the outer window to add it to it's collection, and WPF's DataTemplate awesomeness will take care of the proper display. You'll have to do some fiddling to get tab 'close' operations working the way you want. It's kind of a pain but doable.
If you really want to do MDI, there's nothing built into WPF for it (I think Microsoft has decided that it is a bad UI pattern now?), but there may be 3rd party controls out there for it. Any good one will still mirror this solution where their MDI container control will bind to your list of child window view models.

Accessing a function in another form -- C#

I have this battleship program where i am trying to access a function in another form. This function is used to change the buttons on the game board to either enabled or disabled, depending on who's turn it is. Changing the buttons to enabled and disabled is not my problem. My problem is accessing the function to do it in the other form. I would post code, but it is lengthy and spread between three forms.
Appreciate any help!
Thanks in advance!
Luke
Why not pull the functionality out into its own public class (like ButtonConfigurator or something like that). Then any form can hold a ButtonConfigurator object and use it.
It depends on your code architecture:
Kind of rough one: If you just have several forms Form _form1, Form2 _form2, you can create kind of relationship between them, by, just an example pseudocode:
public class Form1:Form
{
Form2 _form2Object = null;
public Form1(Form2 frm2)
{
_form2Object = frm2;
}
//and after when needed just use that _form2Object to call a mehod on it.
}
More nice one: is declare shared between all your forms event Dispatcher. So when Form1 wants to notify somethign to Form2 it calls Dispatchers relative method, which takes care to call right method on Form2
There could be a lot of other solutions more or less nicer, but it strongly depends on your app architecture. Here I just put down a couple of choices you could have.
Hope this helps.
Regards.
you need pass the instance of the form with Button to the form you call the function, make the function public.
Lets suppose you have a Form form1 which has method method1, that you want to access in Form form2. You could declare that method as public static. This way you could access that method like form1.method1.

Winform & user control - C#

I have a Form and a UserControl. The UserControl has a menu, and the form has a tabstrip (General, Food, Vitamins etc).
In the UserControl, I have the following code: (Form name is frmForm, the tab names in the form are tabGeneral,tabFood, tabVitamins)
frmForm fm=new frmForm();
fm.tabMain.Selected=tabVitamins;
I call these line from the UserControl to capture the tab to get selected on the form, but it does not select the vitamins tab.
Where am I going wrong? I have access specifier as Protected Internal for tabs in the form.
Please advice.
Thanks,
Karthick
When you write new frmForm(), you're creating a completely new instance of frmForm, which is then discarded.
To get the frmForm instance that holds your control, call the FindForm() method and cast to frmForm.
For example:
frmForm myForm = FindForm() as frmForm;
if(myForm != null)
myForm.tabMain.SelectedTab = myForm.tabVitamins;
If the control is on some other form, this code won't do anything.
By the way, Hungarian notation is frowned upon in .Net.
Your form should probably be named something like MainForm.
SLaks has correctly pointed out your fundamental error, and given you a valid example of a way, via a call to the method 'FindForm, to get the Form the UserControl is sited on.
It may be valuable to you to keep in mind that a UserControl (and all Controls) also has a 'Parent property, but, of course, a UserControl could be placed inside another Control on a Form (like your UserControl could be inside a Panel on the Form) : in that case the UserControl's Parent would be the control it's inside on the Form (like, a Panel), not the Form itself, but 'FindForm will do the right thing to get you the Form it's on.
However you are calling a Method every time you use 'FindForm, and "best practice" suggests that what you want to do is to "inject" a reference to the Form into the UserControl at run-time so that it can always access its Form property easily, without calling a 'Method.
In your example, on a practical level, this (calling the Method) may make almost no difference in performance, but, imho, as you get to a place with WinForms and .NET where you might have a UserControl that will need access to its Parent Form very frequently, this will pay off, and it's a better way to structure your code in the long run, for maintenance.
Wes showed you one way you can "embed" (inject) the UserControl's hosting Form : using an overloaded constructor for the UserControl. But that requires you to modify the Designer.cs file in standard WinForms, and I strongly advise you against that, even though it will work. Particularly if you are just "getting your feet on the ground" in .NET, I strongly advise you against modifying it, or anything having to do with the Form's constructor and its internal call to : InitializeComponent();
Also, as you progress with WinForms you are going to meet many situations where you are going to want instances of "objects" (a Control, a Form, an instance of a Class) to contain references to other instances of "objects.
If you can understand and use one simple use of "injection" here, you are going to make progress to make yourself ready to handle more complex .Net programming in the future.
Another way is to put a Public Property in the UserControl that can be set in code from the MainForm. In the UserControl something like :
private frmForm ParentForm;
public frmForm UCParentForm
{
set { ParentForm = value; }
}
So then in your main form's code, perhaps in the Load event like this :
private void frmForm_Load(object sender, EventArgs e)
{
TheUserControl.UCParentForm = this;
}
or when you need to, you set the UserControl's 'ParentForm property once. So you have eliminated using the method 'FindForm().
In this case, if you only want access to a specific control on the UserControl's Parent Form, like a TabControl, you might consider that you want to make the Property you set of type TabControl, rather than Form : the same coding technique shown above can be used in the UserControl :
private TabControl mainFormTabControl;
public TabControl MainFormTabControl
{
set { mainFormTabControl = value; }
}
imho, it is when you are creating UserControls dynamically at run-time, using an overloaded constructor, as Wes suggests, is the best strategy. And using overloaded constructors has many, many others uses in .NET that you'll get into.
good luck !
You should not be creating a new frmForm() inside the user control. You could pass a reference to the frmForm to the user control.
In your user control constructor try something like this.
private frmForm fm;
public YourUserControl(frmForm fm)
{
this.fm = fm;
}
Then you could use.
fm.tabMain.Selected=tabVitamins;
Does that help?

Categories

Resources