How to make an event span over multiple forms - c#

The project I am working on needs a couple buttons on multiple forms, instead of doing the code shown below I was hoping it could be made global.
This is only one part of the project, all the code does is enlarge the button picture when the user hovers over it.
I've tried looking at classes, tags and attributes. I know classes can be made to use across multiple forms but I cant find out if they work with events.
private void btnEnter_MouseEnter(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Size = new Size(299, 102);
}
private void btnLeave_MouseLeave(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Size = new Size(289, 92);
}

You can create an inherited button. Add a new class then make sure you put : Button after the class name.
using System.Drawing;
using System.Windows.Forms;
namespace InheritedButton
{
public class ExpandButton : Button
{
public Size EnterSize { get; set; }
private Size _LeaveSize;
public Size LeaveSize
{
get
{
return (_LeaveSize);
}
set
{
_LeaveSize = value;
this.Size = LeaveSize;
}
}
public ExpandButton() : base()
{
}
protected override void OnMouseEnter(EventArgs e)
{
this.Size = EnterSize;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
this.Size = LeaveSize;
base.OnMouseLeave(e);
}
}
}
Build your project and the new button will appear in the toolbox. Drop it onto a form/control and make sure you set the EnterSize and LeaveSize. EnterSize determines the size of the button when you mouse over and LeaveSize sets the initial size and sets the size of the button when you mouse out. You don't need to set the Size property, just set LeaveSize.
Any time you want to use the expanding/contracting button just use the inherited one instead.

Related

How can I draw a line in my form from another class?

I have 3 classes in my program:
Arrow (it contains the logic for drawing arrow, and all required information about it, like: starting point, ending point, etc.)
Form1 (that contains the drawing area(basically panel), where this arrow will be located in the future)
UserControl, is located in Form1 (I did Form1.Controls.Add(UserControl)). It has a Form1 as a parent. In this UserControl, I have a button, when I click it, an arrow should be drawn on the Form1's drawing area.
And I'm so confused with the logic that this program should have. I tried to create Arrow class object in the UserControl.Button_Click(), and call all the Arrow's methods from there, but I can't access to Form1's controls. I also thought maybe I can create object of Arrow in the Form1. So I tried to subscribe event UserControl.Button_Click() with some Form1's delegate, but I don't know how to do it. In this case, does delegate and the method that this delegate have as a reference should be Static?
So this is how my code looks like.
(I little bit simplified and shortened my classes)
Arrow:
public class Arrow
{
public Point PointBeginning { get => pointBeginning; set => pointBeginning = value; }
public Point PointEnding { get => pointEnding; set => pointEnding = value; }
public int ArrowClickCounter { get => arrowClickCounter; set => arrowClickCounter = value; }
public void Draw(object sender, MouseEventArgs e)
{
//code for drawing
}
}
Form1:
public class Form1
{
public delegate void DrawArrowDelegate(object sender, MouseEventArgs e);
DrawArrowDelegate drawArrowDelegate = DrawArrow;
/* .. */
private void DrawArrow(object sender, MouseEventArgs e)
{
Arrow arrow = new Arrow();
arrow.PointBegining = //some point
arrow.PointEnding = //some another point
arrow.Draw(sender, e);
}
}
UserControl:
public class UserControl
{
/*...*/
private void button_MouseClick(object sender, MouseEventArgs e)
{
//And here i somehow want to call delegate. But don't know how :(
}
}
Sorry for such confused code :(
Can you please recommend me something?
Your Arrow class could potentially have a DrawMethod which takes a control
Your UserControl, should publish events
You form should listen to the UserControl Events
Your form should override OnPaint to draw the method on demand
Arrow class:
public class Arrow
{
public Point PointBeginning { get; set; }
public Point PointEnding { get; set; }
public int ArrowClickCounter { get; set; }
public void Draw()
{
//code for drawing
}
}
UserControl.cs:
public delegate void CreateArrowEventArgs(Arrow arrow);
public event CreateArrowEventArgs OnCreateArrow;
private void button1_Click(object sender, EventArgs e)
{
if(this.OnCreateArrow!=null)
{
// Create Arrow object which you will have access to in your Form
Arrow arrowToDraw = new Arrow();
// Fire The Event
this.OnCreateArrow.Invoke(arrowToDraw);
}
}
Form codebehind :
private void Form1_Load(object sender, EventArgs e)
{
// Create User Control
var UserCtrl = new UserControl1();
// Register Event
UserCtrl.OnCreateArrow += UserCtrl_OnCreateArrow;
//Add Control to Form
this.Controls.Add(UserCtrl);
}
// You get the Arrow object for use here
private void UserCtrl_OnCreateArrow(Arrow arrow)
{
arrow.Draw();
}
It sounds like you're having trouble accessing Form1's Controls, so try this:
Form1 f1 = new Form1();
foreach(Button b in f1.Controls)
{
//Your code..
}
There's also:
this.Controls
And, with calling the events of another control,
button1_Click(sender, e);
As for adding an event to the click of, say, a button,
button1.Click += button1_Click;
Those should work to access the controls.
I can provide more information if needed :)

How to initiate a button click of another page in a method from another cs file

I have a cs file for Drag drop Element. In the Method after the drop is completed (OnManipulationCompleted) I would like to initiate/trigger the 3 button clicks from another WPF page which has 3 buttons within the OnManipulationCompleted method.
namespace KinectDemos
{
public class DragDropElementController : IKinectManipulatableController
{
private ManipulatableModel _inputModel;
private KinectRegion _kinectRegion;
private DragDropElement _dragDropElement;
private bool _disposedValue;
public DragDropElementController(IInputModel inputModel, KinectRegion kinectRegion)
{
_inputModel = inputModel as ManipulatableModel;
_kinectRegion = kinectRegion;
_dragDropElement = _inputModel.Element as DragDropElement;
_inputModel.ManipulationStarted += OnManipulationStarted;
_inputModel.ManipulationUpdated += OnManipulationUpdated;
_inputModel.ManipulationCompleted += OnManipulationCompleted;
}
private void OnManipulationCompleted(object sender,
KinectManipulationCompletedEventArgs kinectManipulationCompletedEventArgs)
{**HERE I WOULD LIKE TO INITIATE THE BUTTON CLICKS**
}
The Other Wpf page which has these buttons having function for three buttons .After each button drop it would navigate to another page.
Public partial class Beauty : Usercontrol
{
Public void Tip_Click (object sender, RoutedEventArgs e)
{
Afterdrop page1 = new Afterdrop
this.content = page1;
}
Public void Tricks_Click (object sender, RoutedEventArgs e)
{
Afterdrop2 page2 = new Afterdrop2
this.content = page2;
}
Public void Invent_Click (object sender, RoutedEventArgs e)
{
Afterdrop3 page3 = new Afterdrop3
this.content = page3;
}
}
How will I do that ?Please help
You need to have an instance of the page you want to trigger events on. If that page exists then you can get that instance based on your application architecture otherwise there is no way to call non-static members without instantiating an object.
Once you get that page instance call the respective event handlers as methods. As an example if that instance is named targetPage then
targetPage.Tip_Click(null, new EventArgs());

How do I bind a button and a label

I extended the button control to have also LabelName. When I press the button I need to write the name of the button in the label.
My first idea was using events - easy and simple.
The question is: Is there more elegant way to do it? (I've been asked to bind the button and the label)...
I think that the best way to do it would be to use an action listener and the best way to use the action listener would be to build it into your class that extends the button control so that the user doesn't have to do this on their own. It would look like this.
class Button2 : Button
{
public string LabelName = "";
public Button2()
{
this.Click += this.SetLabelName;
}
private void SetLabelName(object sender, EventArgs e)
{
this.LabelName = "Something?";
}
//You could also do this instead.
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
}
}
If you're talking about changing the Text property of an external Label control, then simply create a property in your Button to hold a reference to a Label. You can set this via the IDE like any other property:
Here's the Button class:
public class MyButton : Button
{
private Label _Label = null;
public Label Label
{
get { return _Label; }
set { _Label = value; }
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
if (this.Label != null)
{
this.Label.Text = this.Name;
}
}
}
Here's the Label after I clicked the Button:

Show/Hide one User Control from another

I am tinkering around with User Controls and I've found myself stumped. My form has 2 User Controls, a TitleScreen and a MainScreen. I need for the TitleScreen to be visible when the program runs and then invisible when the "new game" button is clicked, at which point the MainScreen needs to be visible. Unfortunately, I can't figure out how to do this.
FormMain.cs
#region Property Region
public UserControls.MainScreen ControlMainScreen
{
get { return controlMainScreen; }
}
#endregion
#region Constructor Region
public FormMain()
{
InitializeComponent();
controlMainScreen.Visible = false;
}
#endregion
TitleScreen.cs
public void btnNewGame_Click(object sender, EventArgs e)
{
this.Visible = false;
FormMain.ControlMainScreen.Visible = true;
}
Obviously it doesn't work, but I've tried everything that I know how to do. I also have no clue how to make controlMainScreen static since I didn't actually make the declaration (VS did). Any help would be appreciated.
You could use ParentForm which is a property on UserControl to get a reference to the parent form.
((YourFormsExactType)(this.ParentForm)).ControlMainScreen.Visible = false;
Add a user control on the Win project and then dynamically add to the Form.
Here is the code:
public Show_hideControl()
{
InitializeComponent();
//Adding First User control
Main _main = new Main();
panel1.Controls.Add(_main);
}
private void button1_Click(object sender, EventArgs e)
{
//removing already added user control
panel1.Controls.Clear();
//Adding second user control
Alternative _alter = new Alternative();
panel1.Controls.Add(_alter);
}

Flashing ToolStripButton

I am using a ToolStrip with a number of ToolStripButtons.
What I would like is to be able to flash one of the buttons to get the user's attention.
For example, if they have made changes to information and need to click the Save button.
If this were a normal button I could do this using a Timer and periodically changing the BackColor however this doesn't work with a ToolStrip.
I could create a Renderer subclass and assign it to the ToolStrip but this appears to only get used in specific situations - i.e. it's event driven.
Does anyone have any ideas?
Well, just use a custom renderer so you can change the color of the button's background. With a timer that blinks it. Add a new class to your project and paste this code:
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Forms;
class BlinkingButtonRenderer : ToolStripProfessionalRenderer {
public BlinkingButtonRenderer(ToolStrip strip) {
this.strip = strip;
this.strip.Renderer = this;
this.strip.Disposed += new EventHandler(strip_Disposed);
this.blinkTimer = new Timer { Interval = 500 };
this.blinkTimer.Tick += delegate { blink = !blink; strip.Invalidate(); };
}
public void BlinkButton(ToolStripButton button, bool enable) {
if (!enable) blinkButtons.Remove(button);
else blinkButtons.Add(button);
blinkTimer.Enabled = blinkButtons.Count > 0;
strip.Invalidate();
}
protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e) {
var btn = e.Item as ToolStripButton;
if (blink && btn != null && blinkButtons.Contains(btn)) {
Rectangle bounds = new Rectangle(Point.Empty, e.Item.Size);
e.Graphics.FillRectangle(Brushes.Black, bounds);
}
else base.OnRenderButtonBackground(e);
}
private void strip_Disposed(object sender, EventArgs e) {
blinkTimer.Dispose();
}
private List<ToolStripItem> blinkButtons = new List<ToolStripItem>();
private bool blink;
private Timer blinkTimer;
private ToolStrip strip;
}
Sample usage in a form with a Toolstrip containing a button:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
blinker = new BlinkingButtonRenderer(toolStrip1);
}
private void toolStripButton1_Click(object sender, EventArgs e) {
blink = !blink;
blinker.BlinkButton(toolStripButton1, blink);
}
private bool blink;
private BlinkingButtonRenderer blinker;
}

Categories

Resources