Guys i have problem with MVP design pattern becouse am not shure how can i show child view in parent form.
My view does not have MdiParent property. Can i manually create it in view interface?
Very ugly look to every form opens in a new window!
I have two presenters:
MainPresenter (represent mainForm(parent) logic)
TaskPresenter (represent logic for save,insert,delete logic)
Two View interfaces:
IMainView
ITaskView
And two winforms:
MainForm - mainwindow(parrent mdi form)
TaskForm
Check code:
MainPresenter
public class MainPresenter
{
private readonly IMainView view;
private List<ITaskModel> tasks;
// Constructor
public MainPresenter(IMainView view)
{
this.view = view;
this.Init();
this.tasks = new List<ITaskModel>();
}
// Initialize
private void Init()
{
this.view.AddTask += AddTask;
}
// Add task
private void AddTask(object sender, EventArgs e)
{
// Show as MDI CHILD
}
}
IMainView
public interface IMainView
{
event EventHandler<EventArgs> AddTask;
}
TaskPresenter
public class TaskPresenter
{
private readonly ITaskView view;
private List<ITaskModel> tasks;
private bool isNew = true;
private int currentIndex = 0;
// Constructor
public TaskPresenter(ITaskView view)
{
this.view = view;
this.Initialize();
}
// Initialize
public void Initialize()
{
tasks = new List<ITaskModel>();
view.SaveTask += Save;
view.NewTask += New;
view.PrevTask += Previous;
view.NextTask += Next;
}
private void Save(object sender, EventArgs e)
{
}
private void New(object sender, EventArgs e)
{
}
private void Next(object sender, EventArgs e)
{
}
private void Previous(object sender, EventArgs e)
{
}
private void BlankTask()
{
}
private void LoadTask(ITaskModel task)
{
}
}
ITaskView
public interface ITaskView
{
String TaskName { get; set; }
String TaskPriority { get; set; }
DateTime? StartDate { get; set; }
DateTime? DuoDate { get; set; }
event EventHandler<EventArgs> SaveTask;
event EventHandler<EventArgs> NewTask;
event EventHandler<EventArgs> NextTask;
event EventHandler<EventArgs> PrevTask;
}
And here is MainForm
public partial class MainForm : Form, IMainView
{
MainPresenter Presenter;
// Construcor
public MainForm()
{
InitializeComponent();
}
// Events
public event EventHandler<EventArgs> AddTask;
// On load
private void MainForm_Load(object sender, EventArgs e)
{
Presenter = new MainPresenter(this);
}
// On click add task btn
private void addTaskBtn_Click(object sender, EventArgs e)
{
if(AddTask != null)
{
// When is this event triggered i want to show another child form for adding new task
AddTask(this, EventArgs.Empty);
}
}
}
So how can i show TaskView as child in MainView?
UIApplication it is Windows Forms Application but output type Class Library.
Add referance MVPFramework
MainForm
public partial class MainForm : Form , IMainView
{
[Resolve]
public IMainControl mainControl;
public MainForm()
{
InitializeComponent();
}
public bool ShowAsDialog()
{
throw new NotImplementedException();
}
private void openChildFormToolStripMenuItem_Click(object sender, EventArgs e)
{
mainControl.OnOpenChildForm();
}
}
Child Form
public partial class ChildForm : Form , IChildView
{
public ChildForm()
{
InitializeComponent();
}
public bool ShowAsDialog()
{
throw new NotImplementedException();
}
public object MDIparent
{
set
{
this.MdiParent = (Form)value;
}
}
}
CoreApplication it is class Library
IMainControl
public interface IMainControl :IControl
{
void OnOpenChildForm();
}
MainControl
public class MainControl :IMainControl
{
[Resolve]
public IApplicationController applicationController;
public void OnOpenChildForm()
{
IChildControl TransfersOnTheWayControl = applicationController.Resolve<IChildControl>();
TransfersOnTheWayControl.Run();
}
}
IChildControl
public interface IChildControl :IControl
{
void Run();
}
IMainView
public interface IMainView :IView
{
}
IChildView
public interface IChildView :IView
{
bool ShowAsDialog();`enter code here`
object MDIparent { set; }
}
IMainPresenter
public interface IMainPresenter :IPresenter
{
}
IChildPresenter
public interface IChildPresenter :IPresenter
{
bool Ask();
}
MainPresenter
public class MainPresenter :BasePresenter<IMainView>, IMainPresenter
{
}
ChildPresenter
public class ChildPresenter : BasePresenter<IChildView>, IChildPresenter
{
public bool Ask()
{
this.Init();
bool res = View.ShowAsDialog();
ApplicationController.ClearInstance<IChildView>();
return res;
}
public override void Init()
{
View.MDIparent = ApplicationController.GetMainFrom<IMainPresenter>();
base.Init();
}
}
LauncherApplication it is Console Application but output type Windows Form.
class Program
{
static void Main(string[] args)
{
IApplicationController applicationController = new ApplicationController(new ServicesContainerAdapter());
applicationController
//RegisterView
.RegisterView<IMainView, MainForm>()
.RegisterView<IChildView, ChildForm>()
//RegisterPresenter
.RegisterPresenter<IMainPresenter, MainPresenter>()
.RegisterPresenter<IChildPresenter, ChildPresenter>()
//RegisterController
.RegisterController<IMainControl, MainControl>()
.RegisterController<IChildControl, ChildControl>();
IMainPresenter mainPresenter = applicationController.Resolve<IMainPresenter>();
mainPresenter.Init();
Application.Run((Form)mainPresenter.FormObject);
}
}
Related
not very expert of Threading under Windows.
I have a Main WinForm that opens a child form in it's ctor.
public partial class Main : Form
{
public Main()
{
InitializeComponent();
ImgRxUI formStart = new ImgRxUI();
formStart.MdiParent = this;
formStart.WindowState = FormWindowState.Maximized;
formStart.Show();
}
etc..
The ImgRxUI Form (child form) starts a Thread passing to 2 Actions (delegates in simple form).
public partial class ImgRxUI : Form
{
private ImgReceiver oImgReceiver = null;
public ImgRxUI()
{
InitializeComponent();
this.WindowState = FormWindowState.Maximized;
this.ShowIcon = false;
oImgReceiver = new ImgReceiver(UpdateImage, Log);
oImgReceiver.startService();
}
public void UpdateImage(byte[] ProtocolType)
{
...do stuff...
}
public void Log(string Text)
{
this.Invoke((MethodInvoker)delegate
{
LogMethod(Text);
tLog.ScrollToCaret();
});
}
private void LogMethod(string Text)
{
tLog.AppendText(Text + Environment.NewLine);
}
The ImgReceiver as I said starts a thread that listens on a socket...
public class ImgReceiver
{
private Action<byte[]> ImgReceived;
private Action<string> Log;
private System.Threading.Thread Thread_ImgReceiver = null;
public ImgReceiver(Action<byte[]> ImageReceivedDelegate, Action<string> LogDelegate)
{
this.ImgReceived = ImageReceivedDelegate;
this.Log = LogDelegate;
}
public void startService()
{
Thread_ImgReceiver = new System.Threading.Thread(startListening);
Thread_ImgReceiver.IsBackground = true;
Thread_ImgReceiver.Start();
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void killService()
{
Thread_ImgReceiver.Abort();
System.Threading.Thread.Sleep(1000);
}
public void startListening()
{ ...do stuff...}
When I close the ImgRxUI form the following event on the form itself gets called
private void ImgRxUI_FormClosing(object sender, FormClosingEventArgs e)
{
oImgReceiver.killService();
}
Hear rises the error in the title.
Wht ?
Thaks
Change the kill Service method to
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void killService(Action action)
{
action.Invoke();
System.Threading.Thread.Sleep(1000);
}
Change the access level Thread_ImgReceiver to public
public System.Threading.Thread Thread_ImgReceiver = null;
and call killService to
private void ImgRxUI_FormClosing(object sender, FormClosingEventArgs e)
{
oImgReceiver.killService(new Action(delegate { oImgReceiver.Thread_ImgReceiver.Abort(); }));
}
I have Parent_1, Parent_2, Parent_3 and etc. and have one Child form
in Parent_1, Parent_2, Parent_3 ... I have:
private string strText;
public string pubText {
get { return strText; }
set { strText = value; } }
on button:
private void btbutton1_Click(object sender, EventArgs e)
{
var form = new fChild(this);
form.ShowDialog();
}
in child form I have the code:
private Parent_1 logicalParent;
public fChild(Parent_1 parent)
{
InitializeComponent();
logicalParent = parent;
this.FormClosed += new FormClosedEventHandler(child_FormClosed);
}
and
void child_FormClosed(object sender, FormClosedEventArgs e)
{
logicalParent.pubText = this.textBox1.Text;
}
This works only for 1 parent form, How Can I use this for other Parent forms???
Please Help
You can create a common interface for the three parent forms:
public interface IParentForm
{
string PubText {get; set;}
}
public class Parent_1 : Form, IParentForm
{
public string PubText
{
get { return this.pubText; }
set { this.pubText = value; }
}
}
//same for Parent_2 and 3
then in your child form declare logicalParent to be of type IParentForm, and change the constructor of the child form to be public fChild(IParentForm parent)
At the button click do the following:
private void btbutton1_Click(object sender, EventArgs e)
{
var form = new fChild(this); // this is not more needed
form.ShowDialog();
pubText = form.pubText;
}
I've created event as bellow and want to listen to it and execute method in another class when it fires
but saveEvent always comes to be null and it doesn't fire
I don't know what I've missed
here's my first class has button
internal partial class OpenSaveReportWizardForm : Form
{
public event EventHandler saveEvent;
private void saveButton_Click(object sender, EventArgs e)
{
saveEvent?.Invoke(this, e);
}
}
and here's the second class where I want to listen to saveEvent
internal class Database
{
public Database()
{
Program._wizardForm.saveEvent += (sender, e) => HandleSaveMethod( );
}
public void HandleSaveMethod()
{
// do something
}
here's where I open the form
internal class Program
{
public static OpenSaveReportWizardForm _wizardForm;
private static void Main()
{
OpenFileCommandHandler();
}
void OpenFileCommandHandler()
{
_wizardForm = new OpenSaveReportWizardForm( );
_wizardForm.ShowDialog();
}
}
Because you disposed wizardForm, after that event is cleared.
You should write next code:
internal class Database
{
private bool _isDisposed;
private OpenSaveReportWizardForm _wizardForm;
public Database()
{
_wizardForm = new OpenSaveReportWizardForm(m_Opening,m_ConnectionProperties,m_ColumnProperties))
_wizardForm.saveEvent += (sender, e) => HandleSaveMethod( );
}
public void HandleSaveMethod()
{
// do something
}
public void Dispose()
{
if(_isDisposed)
return;
_isDisposed = true;
_wizardForm.saveEvent -= HandleSaveMethod;
_wizardForm.Dispose();
}
I have two pages MainPage and PlayPage.Inside MainPage I have a frame and a textblock and inside the frame I have Playpage. When I click a button from play page I change a variable but the textblock doesn't update. How do I do that?
Here is my code:
public class Swag
{
public static int swag = 0;
public void Add(int a)
{
swag += a;
}
public void Reduce(int a)
{
swag -= a;
}
public int Get()
{
return swag;
}
}
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
MyFrame.Navigate(typeof(PlayPage));
SwagMeasurer.Text = Convert.ToString(Swag.Get());
}
}
public sealed partial class PlayPage : Page
{
public PlayPage()
{
this.InitializeComponent();
}
private void Clicker_Click(object sender, RoutedEventArgs e)
{
Swag.swag += 1;
}
}
Handling and Raising Events should be your new friend!
Swag :
public class Swag
{
private static int _swag;
public static void Add(int a)
{
_swag += a;
OnUpdate?.Invoke(new SwagEventArgs(a));
OnAddition?.Invoke(new SwagEventArgs(a));
}
public static void Reduce(int a)
{
_swag -= a;
OnUpdate?.Invoke(new SwagEventArgs(a));
OnSubtraction?.Invoke(new SwagEventArgs(a));
}
public static int Get()
{
return _swag;
}
public static event AddedValueEventHandler OnAddition;
public static event SubtractedValueEventHandler OnSubtraction;
public static event UpdatedValueEventHandler OnUpdate;
public delegate void AddedValueEventHandler(SwagEventArgs e);
public delegate void SubtractedValueEventHandler(SwagEventArgs e);
public delegate void UpdatedValueEventHandler(SwagEventArgs e);
}
Keep in mind, that privacy should be respected!
PlayPage :
public partial class PlayPage : Page
{
public PlayPage()
{
InitializeComponent();
}
private void Clicker_Sub_Click(object sender, RoutedEventArgs e)
{
Swag.Reduce(1);
}
private void Clicker_Add_Click(object sender, RoutedEventArgs e)
{
Swag.Add(1);
}
}
Please note, that I have added a subtraction Button.
MainWindow :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyFrame.Navigate(new PlayPage());
SwagMeasurer.Text = Convert.ToString(Swag.Get());
Swag.OnAddition += Swag_Addition;
Swag.OnSubtraction += Swag_OnSubtraction;
Swag.OnUpdate += Swag_OnUpdate;
}
private void Swag_OnUpdate(SwagEventArgs e)
{
SwagMeasurer.Text = Convert.ToString(Swag.Get());
}
private void Swag_OnSubtraction(SwagEventArgs e)
{
LastMode.Text = "That's a negative";
}
private void Swag_Addition(SwagEventArgs e)
{
LastMode.Text = "That's a positive";
}
}
LastMode is also a TextBlock (reprecenting if the user has dropped or raised his skill level).
SwagEventArgs :
public class SwagEventArgs : EventArgs
{
public SwagEventArgs(int value)
{
Value = value;
}
public readonly int Value;
}
SwagEventArgs is going to be used to store information as event data.
Is there a way to give a User Control custom events, and invoke the event on a event within the user control. (I'm not sure if invoke is the correct term)
public partial class Sample: UserControl
{
public Sample()
{
InitializeComponent();
}
private void TextBox_Validated(object sender, EventArgs e)
{
// invoke UserControl event here
}
}
And the MainForm:
public partial class MainForm : Form
{
private Sample sampleUserControl = new Sample();
public MainForm()
{
this.InitializeComponent();
sampleUserControl.Click += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
// do stuff
}
}
Aside from the example that Steve posted, there is also syntax available which can simply pass the event through. It is similar to creating a property:
class MyUserControl : UserControl
{
public event EventHandler TextBoxValidated
{
add { textBox1.Validated += value; }
remove { textBox1.Validated -= value; }
}
}
I believe what you want is something like this:
public partial class Sample: UserControl
{
public event EventHandler TextboxValidated;
public Sample()
{
InitializeComponent();
}
private void TextBox_Validated(object sender, EventArgs e)
{
// invoke UserControl event here
if (this.TextboxValidated != null) this.TextboxValidated(sender, e);
}
}
And then on your form:
public partial class MainForm : Form
{
private Sample sampleUserControl = new Sample();
public MainForm()
{
this.InitializeComponent();
sampleUserControl.TextboxValidated += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
// do stuff
}
}