UserControl with embedded MonthCalendar problems - c#

I am hoping someone can help me out. I have created a usercontrol in C# for use on a Winform. The control contains various controls including a monthCalendar control however the monthCalendar control is where my problem lies.
I want the parent form that holds my usercontrol to trigger a block of code to query a database using linq when the dateSelected event of the monthCalendar within the usercontrol is triggered. The idea being that the usercontrol should not be aware of the data access side of things so that the usercontrol can be used in other projects.
What I was hoping was that there was a way that I could make the dateSelected event available to the parent form; I have done this successfully with click events etc for other controls I just can't seem to make this work for the monthCalendar as DateSelected uses DateRangeEventHandler rather than the standard EventHandler.
I hope this is clear as i have been around the block with this one so i'm not sure what makes any sense any more :) Any help or advice in how I could go about coding this would be very much appreciated.

Same way you would with the Button events.
In your UserControl, it would look something like this:
public event DateRangeEventHandler DateChanged {
add { monthCalendar1.DateChanged += value; }
remove { monthCalendar1.DateChanged -= value; }
}
Then in your form, like all controls with events:
userControl11.DateChanged += userControl11_DateChanged;
void userControl11_DateChanged(object sender, DateRangeEventArgs e) {
// do something...
}

You can make MonthCalendar public in your UserControl and then in your Form just subscribe to the event using:
this.userControl.Monthcalender.DateSelected += new DateRangeEventHandler(Monthcalender_DateSelected)
or you can create a new event in your UserControl which will be raised on MonthCalendar.DataSelected. and in your Form subscribe to that event, something like:
UserControl:
public UserControl1()
{
InitializeComponent();
this.monthCalendar1.DateSelected += new DateRangeEventHandler(monthCalendar1_DateSelected);
}
public void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e)
{
OnSeChanged(e);
}
public event DateRangeEventHandler SeChanged;
protected virtual void OnSeChanged(DateRangeEventArgs e)
{
if (SeChanged != null)
{
SeChanged(this, e);
}
}
Form:
userControl11.SeChanged += new DateRangeEventHandler(userControl11_SeChanged);

Related

Changing panel control from inside the panel

I am creating an application using WinForms. I have panel in which I show a user control. Inside this user control I have a button. When I click the button, I want to clear the panel and show a different user control. I am trying to do that using the following code:
private void btnCreateOffer_Click(object sender, EventArgs e)
{
var myControl = new WindowsFormsDemo.View.CreateOffer();
MockUpForm.panMain.Controls.Clear();
MockUpForm.panMain.Controls.Add(myControl);
}
This works from the buttons placed directly in the parrent form, but when I use in inside the user control, it says:
'MockUpForm.panMain' is inaccessible due to its protection level
I suppose it has something to do with private/public classes. But I would rather have the "correct" solution, as opposed to just changing everything to public.
Any suggestions on how this is usually done?
Solution 1 (ugly):
Make panMain public in the designer:
Solution 2 (somewhat better):
Provide public methods to achieve such tasks safely:
// MockUpForm code:
public void ClearPanelControls()
{
panMain.Controls.Clear();
}
public void AddControlToPanel(Control c)
{
panMain.Controls.Add(c);
}
And then call these methods instead of publishing the full panel, which makes possible for example to dispose the whole panel and such things...
To access parent form's control from UserControl You can use delegate and event
something like this....
Windows Form (Parent Form) Code....
public Form1()
{
InitializeComponent();
userControl1.CreateOffer += UserControl1_CreateOffer;
}
private void UserControl1_CreateOffer()
{
var myControl = new WindowsFormsDemo.View.CreateOffer();
this.panMain.Controls.Clear();
this.panMain.Controls.Add(myControl);
}
User Control Code...
internal delegate void CreateOfferDelegate();
internal event CreateOfferDelegate CreateOffer;
public UserControl1()
{
InitializeComponent();
}
private void btnCreateOffer_Click(object sender, EventArgs e)
{
CreateOffer();
}

Trigger an event using user Control C#

Suppose If I have a button on a custom made user control that removes the control from the form (Lets call it formX) it is placed in.
private void btnClose_Click(object sender, EventArgs e)
{
this.ParentForm.Controls.Remove(this);
}
Now upon closing this UserControl I want a method in the formX to be called.
I tried doing something like this :
discount.ControlRemoved += new ControlEventHandler(discount_ControlRemoved);
void UserControl_ControlRemoved(object sender, ControlEventArgs e)
{
CallMethod();
}
However this does not work, when removing the userControl from formX the event is not even called in the debugger.
How do I do this?
The event you should be using is the ControlRemoved event on the parent container, likely the Form in this case. You could do this several ways, some may be better than others depending upon what all you want to do, but the following should at least do what you are requesting:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.ControlRemoved += new ControlEventHandler(Form1_ControlRemoved);
}
void Form1_ControlRemoved(object sender, ControlEventArgs e)
{
if (e.Control.Name == "NameOfUserControl") CallMethod();
}
private void CallMethod()
{
// Do stufff...
}
}
This assumes that you have named your User Control instance "NameOfUserControl". There are various ways you could check for the control being removed to be the correct one. You can also make this a bit more dynamic by doing this in the control itself while using delegates to call back to the parent form, etc... This is just a basic example.

How to allow control inside the splitview's pane close the pane in uwp?

I have a customized control inside the splitview's pane. Now I have the method hideinternal() defined inside the control which makes the control invisible. However, at the same time I also want to close the pane. What should I do? (I know it is SplitView.IsPaneOpen = false; I don't know how to get access to it inside the control's code behind)
I would raise an event from within hideinternal that can then be subscribed to in your view where you could hide the Pane.
eg in your Custom Control the event
public event EventHandler CloseSplitViewPane;
public void OnCloseSplitPaneView(object sender, EventArgs e)
{
CloseSplitViewPane?.Invoke(sender, e);
}
in hideinternal
public void hideinternal()
{
OnCloseSplitViewPane(this, new EventArgs());
}
in your view for example MainPage.xaml.cs constructor (Your Custom Control is called MyControl in this example)
public MainPage()
{
this.InitializeComponent();
MyControl.CloseSplitViewPane += (sender, e) =>
{
SplitView.IsPaneOpen = false;
};
}
Hope that helps
I finally defined an event handler inside the control;
public event EventHandler handlesomething;
then in hideinternal I notify the event;
private void hideinternal()
{
doSomething();
this.NotifyEvent(handlesomething);
}
in the main page's XAML I sign the event handler to some events inside the page
<Control
handlesomething ="SomeMethodsInsideMainPage"
/>

Pass Value Selected From a User Control to a Parent

I have a Winform dialog that contains several user controls - all of them are some sort of Datagridview. The main parent has details about a user, and the user controls each have additional details on that person. When my Dialog first loads all of the UserControls work but I am trying to figure out how to update the UserControl2 based on a position change in UserControl1.
So, I am trying to select a row in UserControl1 and have the data in UserControl2 update based on a value that I just selected.
I have tried using MouseDownEvents on the UserControl1 and BindingSourcePositionChanged but I can't figure out how to get the value selected back to my parent form and then use that value to refresh the other datagrids?
I looked at delegates and events but I guess the lack of sleep is making it incredibly hard to comprehend. I understand that I need to create my delegate and event on the UserControl1 and then somehow call it on my mainform but that's where I get stuck and have no clue where to start.
Is this the right direction? Or is there another way to get this done? Can anyone offer up any suggestions on how this works?
Yes this is the correct approach something like the following will provide an event handler that you can use to the retrieve a public property from the UserControl:
public class SomeClass : BaseControl
{
public event EventHandler PersonSelected;
public string Name{get;set;}
protected void FindUser()
{
var find = new Button {ID = (ToString() + "search"), Text = "Search"};
find.Click += delegate(object sender, EventArgs e)
{
if (PersonSelected!= null)
{
//forward this event to the page's event handler
PersonSelected(this, e);
}
};
}
}
public class SomeOtherClass : Page
{
public void Main()
{
var sp = (SomeClass)Control;
sp.PersonSelected += BtnClick;
}
public void BtnClick(object sender, EventArgs e)
{
//Get some value from the (SomeClass)Control here
}
}

How can I make sender in an eventhandler my custom control and not the labels inside it

I created a custom control which is actually just two labels inside a panel. I want to add an event so that when my custom control is clicked (which would really be clicking either one of the labels) it would return the properties of the whole control, I think that would mean that 'sender' in the event handler would be my custom control and not one of the lables. I don't know if I made myself clear but what I mean is to treat the control as a 'whole' when it is clicked mmm anyway hope you get my point.
How can I do this?
Thanks in advance
What you can do is let the custom control consume the event of the label, and in the custom control implement a new event. Then, when the label event fires, you can fire your own event from the custom control.
For example:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public event EventHandler MyCustomClickEvent;
protected virtual void OnMyCustomClickEvent(EventArgs e)
{
// Here, you use the "this" so it's your own control. You can also
// customize the EventArgs to pass something you'd like.
if (MyCustomClickEvent != null)
MyCustomClickEvent(this, e);
}
private void label1_Click(object sender, EventArgs e)
{
OnMyCustomClickEvent(EventArgs.Empty);
}
}
You can get the container object of your label and cast it to your custom control
private void Label1_Click(object sender, System.EventArgs e)
{
Box box = (object as Label).Parent as Box;
if(box != null)
{
//Do what you need here.
}
}

Categories