Hallo,
Thank you for reading. The Answers i get realy helped me, A LOT!
But to the Problem. I have UserControl as a base Class. The child Class adds its Controls on the UserControl, lets call first BaseControl and the second ChildControl.
At BaseControl Level i have some Delegates attached on some MouseEvents.
The Problem is that they will not fire, if there is an Child control added to them. So I know i can Take all the Mouseevents from all the the Childrensevent and tunnle them through. But thats first very dirty an second not enough. Cause i want to like Paint a Border around or move the BaseControl.
So my Question is realy: Is there a way to gain full access to the MouseEvents in at Base Control, if there are ChildControls added?
Thank you lots!
Thomas
EDIT:
Here is the snippets, hope you understand:
public partial class baseControl : UserControl
{
public baseControl()
{
InitializeComponent();
//will not be called
this.MouseUp += delegate(object sender, MouseEventArgs e)
{
// some code
};
}
}
public partial class child : baseControl
{
secretControl childControl;
public child()
{
InitializeComponent();
this.childControl= new secretControl ();
this.childControl.Visible = true;
//... ,more
this.forChildUsePanel.Add(this.childControl);
// works fine , as it will be called
this.childControl.MouseUp += delegate(object sender, MouseEventArgs e)
{
// some code
};
}
}
Reminder: This are snipptes, so for understanding purpose it cut some corners.
Simpelput:
I want to get some Mouse Event on every Control added to the BaseControl.
I believe you should attach the event handler to every single child control and not to the parent control, if you want to intercept it in the child.
What kind of controls are you adding? It might be a solution to customize these controls. If you add a Label for example, make a new MousePassthroughLabel which inherits from Label und whose inbuild MouseEvent simply fires the one of its parent control. Do this once for every type of control and use you own "MousePassthrough"-Controls instead of the native controls.
There is this new Microsoft technology, Reactive Extensions, which will make event-driven programming easier.
Related
This might be kind of beginner question but I searched and didn't find any clear answer!
The main question is: How to inherit properties of a control (specially FlatStyle) from a base form which doesn't have that control in C#?
Details: I have Form1 inherited from baseForm. baseForm has a Panel and a Label control but no Button. In Form1 I added a button named Button1. How can I change the style of that Button through the baseFrom?
I don't want to create a custom control or redesign the button using rectangles or similar ways, but only change that property for all buttons in my application.
UPDATE: I want all of the buttons to be affected, whether they already exist or just added. Not matter in which -if any- container they are.
In baseForm, you could hook the ControlAdded event on the Panel where the Button is to be added, and style appropiately via code. This will work for every form inherited from baseForm.
For example (in baseForm)
public partial class BaseForm : Form
{
public BaseForm()
{
InitializeComponent();
// "myPanel" is the panel where the button will be added in inherited forms
myPanel.ControlAdded += myPanel_ControlAdded;
}
private void myPanel_ControlAdded(object sender, ControlEventArgs e)
{
var button = e.Control as Button;
if (button != null)
{
button.FlatStyle = FlatStyle.Flat;
button.ForeColor = Color.Red;
}
}
}
Just made a really quick test... it works even in design mode:
As an alternative, if you are going to use heavily styled buttons everywhere in your application, you may consider creating a custom control inheriting from Button, and assign the properties there, like:
public class FlatButton : System.Windows.Forms.Button
{
public FlatButton()
{
FlatStyle = FlatStyle.Flat;
}
}
After building, you will find it in the Toolbox (under "[Your Project's] components" tab), or you can cram it on your own control library (in a different solution) and add it permanently to the Toolbox in Visual Studio.
You would need to make use of Reflection
You can use a LINQ query to do this. This will query everything on the form that is type Button
var c = from controls in this.Controls.OfType<Button>()
select controls;
foreach(var control in c)
control.FlatStyle = FlatStyle.Flat;
I'd like to programmatically emulate a click on a node in a TreeView control. There's no clickable method as far I can see (something corresponding to other controls) and I guess that I need to go for the currently selected node.
So I've tried the following:
christmasTreeView.SelectedNode. ???
However, intellisense gave me no hint on what to call in order to fire a clickety-click on the node. How can it be done?
You can do something like:
// find the node you want to select and make it the SelectedNode
christmasTreeView.SelectedNode = christmasTreeView.Nodes[1]; // <-- the index you need
// Now trigger a select
christmasTreeView.Select();
// or
//christmasTreeView.Focus();
This will fire:
private void christmasTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
// awesome
}
Possible approach (not very smooth, though).
TreeNode preSelected = ChristmasTreeView.SelectedNode;
ChristmasTreeView.SelectedNode = null;
ChristmasTreeView.SelectedNode = preSelected;
ChristmasTreeView.Select();
Your main issue is that a Windows Forms TreeNode does not derive from a Control like a TreeView does (or, for example, a Button). It's much closer to a "model" class, meaning that it's primarily concerned with the hierarchical organization of your data. Although some of the presentational abstraction is leaked in properties like Color, Bounds, Handle and similar, a TreeNode doesn't know how to paint itself, nor how to handle click events.
On the other hand, a TreeView is an actual Control, meaning you can derive from it and be able to override its protected OnClick method, like shown in the example you linked.
If you want to follow that path, you could create your derived TreeView class from it and override the protected OnNodeMouseClick method. This method is specific to the TreeView and called by its WndProc method when a certain node is clicked.
But having read your comments to other answers, it seems that this is not what you really need to do to accomplish your goal.
You need to use event handler for TreeView.NodeMouseClick.
This Event got parameter which You can call in Your EventHandler like below:
void MyTreeview_NodeMouseClick(object sender,
TreeNodeMouseClickEventArgs e)
{
// do something with e.Node
}
I have an issue when it comes working with events and/or delegates. I saw very similar questions but still the real implementation is not clear to me. So please when you answer be more specific so I can try and eventually understand how exactly creating/handling of public/custom events work by doing it in a code I know.
What I have is a User Control which is simply a text box and a button I need to change a record in a database using the value from the text box. I'm using this control for many forms so I need to know which entity exactly I'm using and be able to call it's own save method. Doing all that will be easier if I just can use the click event of the button from my User Control and then call the Save() method of the current form.
This is my User Control :
namespace UserControls.CommonControls
{
public delegate void ClickMe(string message);
public partial class ChangeCode : UserControl
{
public event ClickMe CustomControlClickMe;
public ChangeCode()
{
InitializeComponent();
}
private void btnChange_Click(object sender, EventArgs e)
{
if (CustomControlClickMe != null)
CustomControlClickMe("Hello");
//ToDo fill
//MessageBox.Show("To Do: Write the busieness logic.");
}
public void SetTextBoxMask(MaskedTextBox txtBox)
{
txtChange.Mask = txtBox.Mask;
}
}
}
I post it with the last attempt I made to try and implement what I need.
This is one of the form that need to use the Click event from the User Control and more specific the Constructor because if I understand right there is the place where I have to subscribe for the event :
public MaterialEdit()
{
InitializeComponent();
UserControls.CommonControls.ChangeCode. += new ClickMe(button2_Click);
}
UserControls.CommonControls.ChangeCode - this is how I reach my User Control it's named ChangeCode.
From what you pasted it is not clear that you added ChangeCode control to your form. To use the control and it's events and properties, first you must create new instance to it and add it to the form. This is done:
In designer, by dragging control from Toolbox to the form
In code editor, by invoking control constructor and adding new object to control collection
Only then can you handle event of that object. Let's say that you dropped ChangeCode control to a form, and that Visual Studio named it ChangeCode1. You attach a handled to CustomControlClickMe event like this:
ChangeCode1.CustomControlClickMe += new ClickMe(button2_Click);
Code you pasted (UserControls.CommonControls.ChangeCode. += new ClickMe(button2_Click);) is incorrect for several reasons:
Syntactically, left hand side expression ends with . which makes it incorrect assignment target (UserControls.CommonControls.ChangeCode.)
Event name is not provided, only the control name (you need to end left hand side of assignment with what you want to assign to - .CustomControlClickMe)
You are trying to attach handler to a class and not an object
I have two projects in this solution: ProjectA and ProjectB. ProjectA is the main start-up project, and has a reference to ProjectB.
ProjectA has a file called MainForm.cs, which contains a textbox and the main UI.
ProjectB has a class inside Shapes.cs, containing a particular structure we're using. Shapes.cs contains an event that is fired when the user changes some text for that object.
What I need to do is catch that text and set a textbox in MainForm.cs to that text. Is there a way we can do that? Basically I don't see any reference to the main form inside Shapes.cs. I would like to do something like this:
( Shape1.Parent as MainForm ).TextBox1.Text = Shape1.Name;
, assuming the user types a string that gets stored in Shape1.Name. I need to escalate it to the main form.
I have searched around for other questions, and the closest lead I found was Matt Hamsmith's answer on this question. But if it is a good approach I should follow, I do not know how to assign an event handler in the main form to an event in the separate class. I would appreciate any help.
Thanks.
If the form is made up child controls, it should be listening to events on those controls, rather than the controls trying to cast their parent as a particular type. Doing that means your control will only ever work on that Form. It breaks encapsulation.
Listen to an event like this:
public class MainForm : Form
{
Shape _shape1 = new Shape();
public MainForm()
{
InitializeComponent();
_shape.ShapeNameChanged += HandleShapeNameChanged;
}
public void HandleShapeNameChanged(object sender, ShapeChangeEventArgs e)
{
textBox1.Text = e.NewName;
}
}
public class Shape
{
public event EventHandler<ShapNameChangedEventArgs> ShapeNameChanged;
}
I've left it for you to:
Define the ShapeNameChangedEventArgs object to contain whatever state you want it to.
Invoke the event when something on your control changes.
Good luck!
I am embedding usercontrols in a panel and using DevExpress Navigator control to navigate from one to the other. What I am concered about is any implications to this method?
I would give examples of what I am concerned about but then I wouldn't need to ask this question...
I have a primary form, ShellForm that has a docked Navigator Control on the left and a docked Panel Control for the rest. I then dock a User Control, say ucSearchPage, in the Panel when the link is clicked.
public partial class ShellForm : XtraForm
{
private ucSearch searchPage = new ucSearch();
private ucEnrollments enrollmentPage = new ucEnrollments();
private ucGeneral generalInfoPage = new ucGeneral();
private ucContacts contactPage = new ucContacts();
public ShellForm()
{
InitializeComponent();
}
private void ShellForm_Load(object sender, EventArgs e)
{
this.pnlShellHost.DockControl(this.searchPage);
}
private void navSearch_LinkClicked(object sender, DevExpress.XtraNavBar.NavBarLinkEventArgs e)
{
this.pnlShellHost.DockControl(this.searchPage);
}
private void navEnrollment_LinkClicked(object sender, DevExpress.XtraNavBar.NavBarLinkEventArgs e)
{
this.pnlShellHost.DockControl(this.enrollmentPage);
}
The code for DockControl() is as follows -->
public static void DockControl(this Control control, UserControl userControl)
{
userControl.Dock = DockStyle.Fill;
control.Controls.Clear();
control.Controls.Add(userControl);
}
Are there any implications to this approach? Is it just plan stupid?
I am one of those programmers that had to learn to run before walking so I have a tendency to fall flat on my face!
There will be about 30 User Controls in all.
Any insight is welcomed and appreciated!
IMO it is not a bad idea at all to embed user controls. In fact, that is exactly what they were meant for. Because every control inherits from the same base class you can build a tree structure of controls using the Composite pattern. This will allow you to create just about anything you would like.
If you think of a basic web page, this is actually what you are doing anyways: placing one element in another, or embedding them. You can have multiple divs in other divs etc. This is essentially what you are doing when you embed user controls as the user controls render to basic HTML.
Hope this helps.
EDIT: To address the concerns in your comment... I don't think you will have a problem from the data entry standpoint. The reason why is because you are using different user controls for your enrollment control and search control. I'm assuming you are overriding the OnLoad event in each of those user controls right? What happens on post back is that the Search's OnLoad will be hit if the search control was loaded, while the enrollment's OnLoad will be hit if that was loaded.
Because of the polymorphism of the user controls, you can handle the data for those controls separately.