Passing variables from main form to input form - winforms

I have a simple question. I have a main form, and then a startup form from where I can select a new 3D model to generate. When selecting a new 3D model from the startup form, I want to check first whether the previous model I worked on has been saved or not. I simply want to pass a boolean value from the main form to the startup form using a delegate, but I can't seem to access the main form or any of its variables. I thought it would be as simple as saying: <code>frmMain myForm = new frmMain();</code>, but typing frmMain doesn't show up anything in intellisense.
Any hints?

Add a public property on your main form
public bool IsDirty
{
get;set;
}
you can then access this.ParentForm.IsDirty in your startup form,
remember to pass a reference to the main form when you show the startup form ... startupForm.showDialog(this);

Your main form is not accessible to Startup form.You have to store it to something that is accessible at a point where you want to use it.
You can do it by following way also ( along with other ways :)
// This class is mainly used to transfer values in between different components of the system
public class CCurrent
{
public static Boolean Saved = false;
}
make sure you put this class in namespace which is accessible to both the forms.
Now In your frmMain form set the value of CCurrent.Saved and access it in your startup form.

Here's my suggestion:
place a 3DModel object property in your main form:
private Model _model;
Declare your startup form as a Dialog ( like OpenFileDialog) and do something like this:
public void OpenModel()
{
using(var frm=new StartUpForm())
{
if(frm.ShowDialog()==DialogResult.OK))
{
if(_model.IsDirty)
{
if(MessageBox.Show("Model is changed do you want to save it?","",MessageBoxButtons.YesNo)==DialogResult.Yes)
_model.Save();
_model=frm.SelectedModel;
}
}
}
}
your startup form should have a interface like this:
public interface IStartupForm:IDisposable
{
DialogResult ShowDialog(IWin32Window parent);
Model SelectedModel{get;}
}

Related

pass data from one from to another in codenameone

In android we can use intent to pass data from one Acitivity to another .
Generally I use showForm("formname",null) method to shift form.
Is there any class for passing data from one form to another in codenameone ?
And how can I pass data to another form in codenameone?
Just store the data in the state machine class as variables. You can also add the data to the navigation stack using the methods getFormState/setFormState but that's not essential.
If you want to pass data to another form without the GUI Builder you can use getters and setters.
To pass data e.g username from Form A to Form B, create a private variable username in Form B and create getters and setters for the variable.
Then create an instance of Form B in Form A and call the setter method for variable username (setUsername method in Form B) and pass the data as a parameter, and lastly call the show() function on Form B
In Form B:
class FormB extends Form {
private String username;
public String getUsername() {
return this.username;
}
public void setUsername(String name) {
this.username = name;
}
}
In Form A:
class FormA extends Form {
public static void main(String[] args) {
String someName = "Aiotouch Softwares";
Form nextForm = new FormB();
nextForm.setUsername(someName);
nextForm.show();
}
}

Update a wpf label periodically

I am new to WPF and C# im trying to understand how can I update a UI element from a BL class (to keep a seperation between the logic and the UI) the bl gets periodic updates from a c++ network component and should update the form once a new argument comes in (I read on the msdn website but I want to see some concrete examples to make sure I got it right)
Because of your gets periodic updates from a c++ network component comment, I am assuming that you already have a system to update your property. I would expose that property from your business class in a view model class, a class with public properties and ICommand functions designed specifically to supply all of the required data to a view, or UserControl.
To be honest, I wouldn't have that (or any) functionality in a business class (depending what you mean by business class)... I'd personally put it straight into the view model, or have a manager/service class that exposed it.
If you insist on keeping it where it is, you'll have to implement either an event or a delegate in your business class so that users of that class can be alerted as to when the value changes. Then you could simply attach a handler to your event/delegate from the view model class and easily update the exposed property whenever the actual property changes.
So it would go a little something like this... in your business class (I am assuming that your value is an int, but you can change this if it is incorrect... the principal is the same):
public delegate void FieldUpdate(int value);
public FieldUpdate OnFieldUpdate { get; set; }
...
private int field;
public int Field
{
get { return field; }
set
{
if (value != field)
{
field = value;
if (OnFieldUpdate != null) OnFieldUpdate(field);
}
}
}
Then in your view model:
private YourBusinessClass instance = new YourBusinessClass();
public YourBusinessClass Instance
{
get { return instance; }
set { instance = value; NotifyPropertyChanged("Instance"); }
}
Attach a handler:
instance.OnFieldUpdate += OnBusinessClassFieldUpdate;
...
public void OnBusinessClassFieldUpdate(int value)
{
Instance = value;
}
Now whenever the field is updated in the business class, the view model (and data bound UI controls) will automatically update via the delegate.

MVVM Light, Windows Phone, View & ViewModel navigation between pages

I have a page where you basically select a set of options (configuration), and then you go to a next page, where you do some stuff
Using the MVVM Light toolkit, I have a viewmodel that binds to the view of the first page. when the user hits a button, it redirects to another view, which would be the 2nd page
i.e.:
Page2Command = new DelegateCommand((obj) =>
Messenger.Default.Send<Uri>(new Uri("/DoStuffView.xaml", UriKind.Relative),
Common.CommonResources.GoToDoStuffRequest)) });
The problem is, the viewmodel for the 2nd view (the way that I see it) has a couple of parameters in the constructor, which are basically the dependencies on the configuration that was set on the first page.
i.e. :
public DoStuffViewModel(ICollection<Note> availableNotes, SoundMappers soundType)
{
}
The problem lies here.. How can I instantiate the viewmodel with this data that was dynamically selected by the user on the 1st page?.
I can't use the ViewModelLocator pattern that MVVM light provides, since those viewmodels don't have any dependencies, they are just by themselves (or they can retrieve data from a db, file or whatever, but they don't have any dynamic input data). I could do it through the view's constructor, instantiate there the viewmodel, and assign to the view's DataSource the newly created viewmodel, but I think that's not very nice to do.
suggestions?
As I see you send messsage using Messenger class so you are familiar with messaging in MVVM light. You have to define your own message type that should accept your parameters from page 1:
public class Page2ViewModelCreateMessage : MessageBase
{
public ICollection<Note> AvailableNotes{get;set;}
public SoundMappers SoundType{get;set;}
public Page2ViewModelCreateMessage ()
{
}
public Page2ViewModelCreateMessage(ICollection<Note> availableNotes, SoundMappers soundType)
{
this.AvailableNotes = availableNotes;
this.SoundType = soundType;
}
}
You have to send an Page2ViewModelCreateMessage instance with you parameters and send it on navigating:
var message = new Page2ViewModelCreateMessage(myAvailableNotes, mySoundType)
Messenger.Default.Send(message);
On Page2 you have to register for recieving message of type Page2ViewModelCreateMessage:
Messenger.Default.Register<Page2ViewModelCreateMessage>(this, OnPage2ViewModelCreateMessage);
..
public void OnPage2ViewModelCreateMessage(Page2ViewModelCreateMessage message)
{
var page2ViewModel = new Page2ViewModel(messsage.AvailableNotes, message.SoundType);
}
As you can see I have replace your DoStuffViewModel with Page2ViewModel to be more clear.
I hope this will help you.
NOTE:I dont guarantee that code will work as its written in notepad.
The way I do this is to have a central controller class that the ViewModels all know about, via an interface. I then set state into this before having the phone perform the navigation for me. Each ViewModel then interrogates this central class for the state it needs.
There are a number of benefits to this for me:
It allows me to have non-static ViewModels.
I can use Ninject to inject the concrete implementation of the controller class and have it scoped as a singleton.
Most importantly, when tombstoning, I only need to grab the current ViewModel and the controller class.
I ran into a problem with messaging where my ViewModel was the registered listener, because I was View First and not ViewModel First, I was forced to use static ViewModel references. Otherwise the ViewModel wasn't created in time to receive the message.
I use the controller class in conjunction with messages (it is basically the recipient of all messages around the UI) so in future if I refactor, I don't need to change much, just the recipients of the messages.
Come to think of it, the controller class is also my navigation sink - as I have some custom navigation code that skips back paging on certain pages etc.
Here's an example of my current set up:
public interface IController
{
Foo SelectedFoo { get; }
}
public class ViewModel
{
private IController _controller;
public ViewModel(IController controller)
{
_controller = controller;
}
private void LoadData()
{
// Using selected foo, we load the bars.
var bars = LoadBars(_controller.SelectedFoo);
}
}
You could use PhoneApplicationService dictionary to save data you need when navigation from first event, and parse it when you navigateTo second page. you can also use that data in your ViewModels.
Something like this:
PhoneApplicationService.Current.State["DatatFromFirstPage"] = data;
and when navigating to second page:
if (PhoneApplicationService.Current.State.ContainsKey("DatatFromFirstPage"))
{
var dataUsedOnSeconPage= PhoneApplicationService.Current.State["DatatFromFirstPage"];
}
you can use this data globally in entire app

C# setting form.visible = false inside a method?

hi i have this lines of code that i cant make it work
the goal is simple setting the form1 to visible = false
public static void DoActions(string Cmd){
if(Cmd == true)
{
MainForm.Visible = false;
}
}
but i keep on having this error
An object reference is required for
the non-static field, method, or
property
usually i set the called methond to static.. so the error will go away
but on this case how do i do it?
thanks for any help guys
'System.Windows.Forms.Control.Invoke(System.Delegate)'
This is happening because DoActions is a static method rather than an instance method, however MainForm is an instance field / property. The distinction is that instance methods operate on an instance of the class on which they are defined, wheras static methods do not.
This means that wheras instance methods are able to access properties, fields and methods of their containing class through the this keyword, for example:
// Instance field
Form1 MainForm;
void InstanceMethod()
{
Form1 frm = this.MainForm;
}
You cannot do the same thing from inside a static method (think about it, what instance would it operate on?). Note that C# will implicitly assume the use of the this keyword in places where it makes sense (so the above example could have been written as Form1 frm = MainForm).
See C# Static Methods for an alternative explanation of static vs instance methods (this is an important concept in object oriented programming that you should take the time to understand properly).
In your example you probably want to change DoActions to an instance method (by removing the static declaration):
public void DoActions(string Cmd)
{
if(Cmd == true)
{
this.MainForm.Visible = false;
}
}
This will allow it to access the instance MainForm field / property, however this may cause problems elsewhere in your code in places where you attempt to call DoActions from another static method without supplying an object instance.
Set form opacity and showintaskbar property in property window:
this.Opacity = 0;
this.ShowInTaskbar = false;
Your method is static - and so cannot access MainForm.
Make your method non-static if it is not required to be so.
public void DoActions(string Cmd)
{
if(Cmd == true)
{
MainForm.Visible = false;
}
}
If it is required, then create a static field in your class and ensure it is set before this method runs.

Winforms: access class properties throughout application

I know this must be an age-old, tired question, but I cant seem to find anything thru my trusty friend (aka Google).
I have a .net 3.5 c# winforms app, that presents a user with a login form on application startup. After a successful login, I want to run off to the DB, pull in some user-specific data and hold them (in properties) in a class called AppCurrentUser.cs, that can thereafer be accessed across all classes in the assembly - the purpose here being that I can fill some properties with a once-off data read, instead of making a call to the DB everytime I need to. In a web app, I would usually use Session variables, and I know that the concept of that does not exist in WinForms.
The class structure resembles the following:
public class AppCurrentUser {
public AppCurrentUser() { }
public Guid UserName { get; set; }
public List<string> Roles { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
Now, I have some options that I need some expert advice on:
Being a "dumb" class, I should make the properties non-static, instantiate the class and then set the properties...but then I will only be able to access that instance from within the class that it was created in, right?
Logically, I believe that these properties should be static as I will only be using the class once throughout the application (and not creating new instances of it), and it's property values will be "reset" on application close. (If I create an instance of it, I can dispose of it on application close)
How should I structure my class and how do I access its properties across all classes in my assembly? I really would appreciate your honest and valued advice on this!!
Thanks!
Use the singleton pattern here:
public class AppUser
{
private static _current = null;
public static AppUser Current
{
get { return = _current; }
}
public static void Init()
{
if (_current == null)
{
_current = new AppUser();
// Load everything from the DB.
// Name = Dd.GetName();
}
}
public string Name { get; private set; }
}
// App startup.
AppUser.Init();
// Now any form / class / whatever can simply do:
var name = AppUser.Current.Name;
Now the "static" things are thread-unsafe. I'll leave it as an exercise of the reader to figure out how to properly use the lock() syntax to make it thread-safe. You should also handle the case if the Current property is accessed before the call to Init.
It depends on how you setup your architecture. If you're doing all your business logic code inside the actual form (e.g. coupling it to the UI), then you probably want to pass user information in as a parameter when you make a form, then keep a reference to it from within that form. In other words, you'd be implementing a Singleton pattern.
You could also use Dependency Injection, so that every time you request the user object, the dependency injection framework (like StructureMap) will provide you with the right object. -- you could probably use it like a session variable since you'll be working in a stateful environment.
The correct place to store this type of information is in a custom implementation of IIdentity. Any information that you need to identify a user or his access rights can be stored in that object, which is then associated with the current thread and can be queried from the current thread whenever needed.
This principal is illustrated in Rocky Lhotka's CLSA books, or google winforms custom identity.
I'm not convinced this is the right way but you could do something like this (seems to be what you're asking for anyway):
public class Sessions
{
// Variables
private static string _Username;
// properties
public static string Username
{
get
{
return _Username;
}
set
{
_Username = value;
}
}
}
in case the c# is wrong...i'm a vb.net developer...
then you'd just use Sessions.USername etc etc

Resources