I have some problems with simple variable sharing between different views.
I have first main view called MainPage.xaml and second called Page2.xaml.
I want to check which radiobutton on MainPage.xaml is checked and send a variable with that date to Page2.xaml.
MainPage:
namespace IDG
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public string choice;
public MainPage()
{
this.InitializeComponent();
}
private void bt_start_Click(object sender, RoutedEventArgs e)
{
if (rb_choice1.IsChecked == true)
{
choice = "choice1";
}
if (rb_quiz.IsChecked == true)
{
this.Frame.Navigate(typeof(Page2), choice);
}
}
}
}
And Page2:
namespace IDG
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Page2 : Page
{
private string x;
public Page2()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var param = e.Parameter as string;
x = param;
textBlock1.Text = x;
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
}
And I want this parameter to be stored in main class, how to do it?
On Page 2 in the OnNavigatedTo event retreive the value like this: var param = e.Parameter as string
EDIT
Assign the retreived parameter to the textblock in the OnNavigatedTo. At the time the page is constructed the value of x is "".
public sealed partial class Page2 : Page
{
private string x="";
public Page2()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
x = e.Parameter as string;
textBlock1.Text = x;
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
Recently, I'm working on WPF project but we use it with DevExpress library, and for your issue, it's very easy to be fixed with Messenger in DevExpress.
We just register the messenger where you want to receive the data,
public class Message {
//...
}
public class Recipient {
public Recipient() {
Messenger.Default.Register<string>(this, OnMessage1);
Messenger.Default.Register<Message>(this, OnMessage2);
}
void SendMessages() {
Messenger.Default.Send("test");
Messenger.Default.Send(new Message());
}
void OnMessage1(string message) {
//...
}
void OnMessage2(Message message) {
//...
}
}
And then you can send it from another view,
public class InheritedMessage : Message {
//...
}
public class Recipient {
public Recipient() {
//Inherited messages are not processed with this subscription
Messenger.Default.Register<Message>(
recipient: this,
action: OnMessage);
//Inherited messages are processed with this subscription
Messenger.Default.Register<Message>(
recipient: this,
receiveInheritedMessagesToo: true,
action: OnMessage);
}
void SendMessages() {
Messenger.Default.Send(new Message());
Messenger.Default.Send(new InheritedMessage());
}
void OnMessage(Message message) {
//...
}
}
With it, you can pass data between modules (or views, but recommend to use MVVM)
If you want to know more about DevExpress, please go through https://documentation.devexpress.com/#WPF/CustomDocument17474
Hope it could help you. :)
Related
So I'm making this small program for my assignment at university and I'm finding it hard to add to my list in my form. Here is my code:
public partial class WorkOutBeam : Form
{
Check checkLib;
public BindingList<ListBox> list;
public WorkOutBeam()
{
InitializeComponent();
}
public void StartForm(object sender, EventArgs e)
{
list = new BindingList<ListBox>();
listBox1.DataSource = list;
}
private void NewForce_Click(object sender, EventArgs e)
{
NewForceName forceItem = new NewForceName();
forceItem.Show();
}
public void AddToForceList(string name)
{
list.Items.Add(name);
}
}
NewForceName class below:
public partial class NewForceName : Form
{
public WorkOutBeam workOutBeam;
public NewForceName()
{
InitializeComponent();
}
private void OkButton_Click(object sender, EventArgs e)
{
if (NewForceNames.Text != "")
{
ReferToLibs();
workOutBeam.AddToForceList(NewForceNames.Text);
Close();
}
}
private void ReferToLibs()
{
workOutBeam = new WorkOutBeam();
}
private void NewForceName_Load(object sender, EventArgs e)
{
}
}
So I say to my program, "give me a new force." When it does, it initializes a new form of "NewForceName." I type into a text box and click 'Ok', this starts a public method shown below:
The list is a binding list which refers to the listBox as a data source. However the program tells me that the Items part is inaccessible due to its protection but I don't know how to add it as public. I tried looking in the properties of my listBox but to no avail.
Give this a shot:
public partial class WorkOutBeam : Form
{
Check checkLib;
// public BindingList<ListBox> list; // get rid of this for now
public WorkOutBeam()
{
InitializeComponent();
}
/*public void StartForm(object sender, EventArgs e)
{
list = new BindingList<ListBox>();
listBox1.DataSource = list;
}*/
private void NewForce_Click(object sender, EventArgs e)
{
NewForceName forceItem = new NewForceName(this); // pass a reference to this
// instance of WorkoutBeam
forceItem.Show();
}
public void AddToForceList(string name)
{
// we should do some more things here, but let's keep it simple for now
listBox1.Items.Add(name);
}
}
And
public partial class NewForceName : Form
{
public WorkOutBeam workOutBeam;
public NewForceName( WorkoutBeam beam ) // we take a WorkoutBeam instance as CTOR param!
{
InitializeComponent();
workoutBeam = beam;
}
private void OkButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(NewForceNames.Text))
{
workOutBeam.AddToForceList(NewForceNames.Text);
Close();
}
}
// DO NOT create new WorkoutBeams every time. Use the original.
/*private void ReferToLibs()
{
workOutBeam = new WorkOutBeam();
}*/
}
Disclaimer: I did not address each and every problem in this code. This is just enough so that it should "work" as intended.
I'm struggling to implement the injection of dependencies using ASP.net. I have created a simple project in winforms which uses the MVP Passive View pattern. I see lots of variations of this pattern online. Many examples I see have the View responsible for instantiating the Presenter. Others have the Presenter create the View. I chose to let a separate winforms project run first and on the click of a button, create my View, Model and Presenter and have the view passed in to the Presenters constructor. This let me avoid direct references between the three layers such that they only kept a reference to a Library of Interfaces. So far so good and everything worked as hoped. I had heard that if I had managed to keep the View as "dumb" as possible that moving to ASP.net would not be too difficult since the main logic presided in the Presenter.
My next move was to recreate the solution in ASP.net webforms and just replace the UI/View with a webform in whoch the code-behind implemented my IView Interface. All my classes successfully compiled without issue but when I run the program I get a NullReferenceException :object reference not set to an instance of an object. This happens as the Presenter tries to set the view property of a textbox. It seems like the textbox has not been created. If I compare the start sequence of the webforms app with the winforms app then I see that the winforms app runs through the View when it is created and registers each control and property. This does not happen with the webform even though I use the same approach for both.
Here is the separate webform which loads first:
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using POCOClassLibrary;
using InterfaceLibrary;
using AppointmentModel;
using AppointmentsPresenter;
using WebFormMVP;
namespace WebDriver
{
public partial class WebDriver : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLaunch_Click(object sender, EventArgs e)
{
IAppointmentView view = new frmAppointmentView();
IAppointmentModel<Appointment> model = new AppointmentsModel();
new AppointmentPresenter(view, model);
view.Show();
}
}
}
This loads and the button appears, next on clicking it reaches the Presenter class (not all shown here):
namespace AppointmentsPresenter
{
//The Presenter is the go-between for the View and Model. It sets the properties in the View to be displayed and
//Stores and Gets the data from the Model. It responds to events raised by the View.
public class AppointmentPresenter
{
private readonly IAppointmentView _view; //references the View Interface
private readonly IAppointmentModel<Appointment> _model; //references the Model Interface
/// <summary>
/// The List of Appointments is created and stored in the Model.
/// In reality we would be using a Database and not a List<>.
/// </summary>
private List<Appointment> appointments;
//maintenace of state:
private int currentIndex = 0;
private bool isNew = true;
private string navigationstatus = "next";
///Presenter constuctor which allows us to pass in the View and Model as interfaces - exposing their events,
/// methods and properties.
public AppointmentPresenter(IAppointmentView view, IAppointmentModel<Appointment> model) //dependencies passed into contructor
{
this._view = view;
this._model = model;
Initialize();
}
private void Initialize()
{
appointments = _model.CreateList(); //Creates and returns List of Appointments in the Model
//lets us manipulate the List that the Model creates.
_view.SaveAppointment += Save_Appointment; //Subscribe to the View events.
_view.NewAppointment += New_Appointment;
_view.PreviousAppointment += Previous_Appointment;
_view.NextAppointment += Next_Appointment;
_view.YesButtonClick += YesButtonClicked;
_view.NoButtonClick += NoButtonClicked;
BlankAppointment();
_view.StatusChange = "Ready";
}
private void BlankAppointment()
{
_view.AppointmentName = string.Empty;
_view.Priority = "Low";
_view.StartDate = null;
_view.DueDate = null;
_view.CompletionDate = null;
_view.Completed = false;
}
When it reaches the BlankAppointment() method and tries to set the _view.AppointmentName property is when things go awry and the NullReferenceException is thrown.
Here is some of the View, I have tried to remove the majority of logic outside and just implement properties and events here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using InterfaceLibrary;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
namespace WebFormMVP
{
public partial class frmAppointmentView : System.Web.UI.Page, IAppointmentView
{
public string AppointmentName
{
get { return txtAppointment.Text; }
set { txtAppointment.Text = value; }
}
public string Priority
{
get { return cboPriority.Text; }
set { cboPriority.Text = value; }
}
public string StartDate
{
get { return txtStartDate.Text; }
set { txtStartDate.Text = value; }
}
public string DueDate
{
get { return txtDueDate.Text; }
set { txtDueDate.Text = value; }
}
public string CompletionDate
{
get { return txtCompletionDate.Text; }
set { txtCompletionDate.Text = value; }
}
public bool Completed
{
get { return chkCompleted.Checked; }
set { chkCompleted.Checked = value; }
}
public bool isDirty { get; set; }
public bool NewButtonVisible
{
set { btnNew.Visible = value; }
}
public bool SaveButtonVisible
{
set { btnSave.Visible = value; }
}
public bool NextButtonVisible
{
set { btnNext.Visible = value; }
}
public bool PreviousButtonVisible
{
set { btnPrevious.Visible = value; }
}
public bool YesButtonVisible
{
set { btnYes.Visible = value; }
}
public bool NoButtonVisible
{
set { btnNo.Visible = value; }
}
public string StatusChange
{
set { lblStatus.Text = value; }
}
public event EventHandler<EventArgs> NewAppointment;
public event EventHandler<EventArgs> NextAppointment;
public event EventHandler<EventArgs> NoButtonClick;
public event EventHandler<EventArgs> PreviousAppointment;
public event EventHandler<EventArgs> SaveAppointment;
public event EventHandler<EventArgs> YesButtonClick;
public void Show()
{
this.Show();
}
protected void Page_Load(object sender, EventArgs e)
{
this.isDirty = false;
}
private void btnSave_Click(object sender, EventArgs e)
{
if (SaveAppointment != null)
{
SaveAppointment(this, EventArgs.Empty);
}
}
private void btnNew_Click(object sender, EventArgs e)
{
if (NewAppointment != null)
{
NewAppointment(this, EventArgs.Empty);
}
}
private void btnPrevious_Click(object sender, EventArgs e)
{
if (PreviousAppointment != null)
{
PreviousAppointment(this, EventArgs.Empty);
}
}
private void btnNext_Click(object sender, EventArgs e)
{
if (NextAppointment != null)
{
NextAppointment(this, EventArgs.Empty);
}
}
private void btnYes_Click(object sender, EventArgs e)
{
if (YesButtonClick != null)
{
YesButtonClick(this, EventArgs.Empty);
}
}
private void btnNo_Click(object sender, EventArgs e)
{
if (NoButtonClick != null)
{
NoButtonClick(this, EventArgs.Empty);
}
}
private void txtAppointment_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void cboPriority_SelectedIndexChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void txtStartDate_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void txtDueDate_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void txtCompletionDate_TextChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
private void chkCompleted_CheckedChanged(object sender, EventArgs e)
{
this.isDirty = true;
}
}
}
Form my searches so far it seems like there may be a problem with implementing the injection into the Presenters constructor in webforms and that I would need to override the PageHandler class to resolve the dependencies however the examples I have looked at so far have the Presenter being created first by the View. I would like to avoid this if at all possible and use a separate webform Page to instantiate the Model, View, Presenter and resolve the dependencies this way.
Apologies if I haven't been clear - I am very wet behind the ears with both MVP and ASP.net Webforms. Any advice would be greatly appreciated as I am pretty confused as to how I might solve this puzzle. ;D
trying to get data from the main form to form 2. The main form has a textbox
and a button. when the button is pressed it opens form 2 which will display the data entered in the main form as a series of text blocks.
However I cant get the data to transfer between the forms. the code is bellow.
can anyone help or suggest anything I can do differently?
WPF 1 main form:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnOpenForm_Click(object sender, RoutedEventArgs e)
{
//btnset: Takes the values contained in the text boxes and updates
//the student class
//properties.
Student.sFname = firstname.Text;
Student.sSname = secondname.Text;
Window1 details = new Window1();
details.Show();
}
WPF 2 code:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void details_Load(object sender, EventArgs e)
{
Fname.Text = Student.sFname;
Sname.Text = Student.sSname;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
There are a number of ways to "pass data" between 2 classes. The easiest way is to expose property or method on Window1 and just set the text you need passed. Another way is to create a constructor on Window1 that takes in the data as parameters. Here is code that demonstrates these approaches.
public class Program
{
public static void Main(string[] args)
{
var c1 = new Class1();
c1.DoStuff();
}
}
public class Class1
{
public void DoStuff()
{
var c = new Class2("stuff");
var c2 = new Class2();
c2.AcceptStuff("stuff2");
c.Print();
c2.Print();
c2.MyData = "stuff3";
c2.Print();
}
}
public class Class2
{
private string _myData;
public Class2()
{
}
public Class2(string myData)
{
_myData = myData;
}
public string MyData
{
set { _myData = value;}
}
public void AcceptStuff(string myData)
{
_myData = myData;
}
public void Print()
{
Console.WriteLine(_myData);
}
}
Prints
stuff
stuff2
stuff3
I assume you have a class in MainWindow like:
`Public class Student
{
public static string sFname;
public static string sSname;
}`
When you click open button you are assigning values to those variable, but if you want to access them in another window mention the window name and then class name.
Check this code if its working?
`public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void details_Load(object sender, EventArgs e)
{
Fname.Text = MainWindow.Student.sFname;
Sname.Text = Mainwindow.Student.sSname;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}`
I have a problem with my code. Its working fine and there is no error but a logical one i think so. I have used a method PassValue(int id) to get value from another from. I have tested it and the forms are exchanging the values correctly but the problem comes when I use the value which i have received from other form as a "textbox.text" or a "label.text"
Here is my code:
namespace MyProgram
{
public partial class UserProfile : Form
{
public string empidstr;
public UserProfile()
{
InitializeComponent();
}
public void PassValue(int id)
{
string idstring = Convert.ToString(id);
// empidlabel.Text = idstring;
empidstr = idstring;
}
private void button2_Click(object sender, EventArgs e)
{
empidlabel.Text = empidstr;
}
private void UserProfile_Load(object sender, EventArgs e)
{
}
}}
I'm trying to subscribe to the the save button event of a user control that is launched in a separate radwindow from the calling parent. but I am getting object not initialized error, I know why but what am I missing?
Update: I found my error but it appears that if (this.SaveEvent!= null) in the ControlBase is always null
Parent Control Code:
public partial class myControl : ControlBase
{
private myChildControl __myChildControl;
private void myControl_PreRender(object sender, EventArgs e)
{
// error occurs here
//this.__myChildControl.SaveEvent += new myChildControl.SaveEventHandler(__myChildControl_SaveEvent);
// found my error
this.SaveEvent += new myChildControl.SaveEventHandler(__myChildControl_SaveEvent);
}
private void __myChildControl _SaveEvent(object sender, CustomEventArgs e)
{
this.Label1.Text = e.CustomEventArg1.ToString();
this.Label2.Text = e.CustomEventArg2.ToString();
}
}
Child Control Launched in RadWindow:
public partial class myChildControl : ControlBase
{
protected void btnSave_OnClick(object sender, EventArgs e)
{
CustomEventArgs _cea = new CustomEventArgs {CustomEventArg1 = 123, CustomEventArg2 = 12};
callBaseMethod(_cea);
}
}
ControlBase Code:
public class ControlBase : UserControl
{
public event CustomEventHandler SaveEvent;
public delegate void CustomEventHandler(object sender, CustomEventArgs e);
internal void callBaseMethod(CustomEventArgs cea)
{
if (this.SaveEvent!= null)
{
this.SaveEvent(this, cea);
}
}
}
CustomEventArgs class:
public class CustomEventArgs : EventArgs
{
public int CustomEventArgs1 { get; set; }
public int CustomEventArgs2 { get; set; }
}
This isn't possible in codebehind: the RadWindow presents a separate aspx/ascx page altogether that is linked to the main page through javascript alone.
What you need to do is handle the RadWindow OnClientClose event in javascript, then fire something in the parent page that performs the appropriate tasks.