How to disable the capture of a Click event - c#

Using VS2010 on .NET v4 I have the following problems.
I have created two custom Controls, Cell and Board and I want to use the Cell control to capture a number of events and to display some data. The most important event I need to capture is the Click event.
When the custom control has no child control items this is not a problem.
At the level wher Cell is used I can bind an event handler to the Click event with no problem.
public partial class Cell : UserControl
{
....
}
public partial class Board : UserControl
{
private void InitializeComponent()
{
...
this.Cell99.Click += new System.EventHandler(this.Cell_Click);
...
}
}
The Cell control is rather small (about 50x50 pixels in size) and one of the things I want it to display is an integer value as big as possible (about 50 x 50 pixes in size ;-) No problem in doing that, I want to use a Label control for that.
As soon as I add another (e.g. Label) control to Cell it no longer can see some events because the child event is getting 'first rights' on it. For the pixels that are covered by the Label control it will capture the Click event that I want to handle with the Cell control and not with the Label contol.
If it was only one control that I want to use in Cell the solution would be to link the event from the Label control to the Cell control. But I have at least 10 different (Label) controls that need to go in Cell to display all the information I have. Forwarding all the events for all the controls to its parent looks like a bit of a hassle to me. (Except from being prone to errors and other bugs.)
What is the propper way of disabling event capturing for child controls in a user control?
As said I have thought of forwarding events from child to parent but rejected that for now.
Then I have thought of not using controls to display the data but generate a bitmap with the information in it and use that as a background. I'm... not looking forward to that!
And finaly I came with an idea of putting one extra control, on top of all the others, and forward the events it's captures to the parent. That might be the simplest way to continue.
Somehow I thing there must be a better way to approach this problem but how?
Any advise is welcome.

Implement a label class which inherits from Windows.Forms.Label. In this derived label/component class add a method or mechanism to forward any click event received by the label to the parent Cell control. Any labels which are added as child controls of a Cell would be of this custom label class and would all forward their Click events to the parent without having to manually do so for each label instance.

Related

Drawing control from Control.Controls in C# Windows Forms

Good day. How to add user control to another user control without using the Control.Controls property? For example, draw a Button on the MyControl : Control object, that the events of button be available? I want to create MyControl that contains another controls, but the Control.Controls collection must be empty, as in all standard WinForms controls.
When you add control to MyControl, it will be something like
this.Controls.Add(control);
otherwise control is not displayed. So you can not avoid this.
What is the problem to have controls in Controls ? Standard controls are not composed from other controls (there are exceptions though: DataGridView in edit mode and PropertyGrid, maybe more).
However you can use dirty tricks, like:
add control to a parent, wiring up necessary events to MyControl;
mimic control (to example, Label, by outputting text in OnPaint event).
Wouldn't it be much easier to fight with that what has problem with Controls (if there is actually any problem) ?

How do I create a Tab Control with no Tab Header in Windows form?

I have created a Windows form using a Tab Control, but it has a header with it. I want to hide it. I am not able to do it using any properties of the Tab Control. Is there any property defined for hiding the tab header for the Tab Control without going through the code?
Use following code to hide the tabs or set these properties in design.
tabControl.Appearance = TabAppearance.FlatButtons;
tabControl.ItemSize = new Size(0, 1);
tabControl.SizeMode = TabSizeMode.Fixed;
You want the tab panels without the feature allowing a user to switch between them, so I suppose you want to create few separate sets of controls to be shown to the user one at a time. You can achieve this in several ways (you can choose one of them if you find it appropriate in your case):
Use several Panel controls instead of several tabs in the TabControl, however, it would be hard to work in the designer, because all the controls would be visible
Use different Forms instead of tabs to keep the layout parts separated. It can be ok, but you may not want to use multiple Forms, so it depends on a specific case.
and finally, the suggested solution:
Encapsulate each set of controls in a UserControl. This allows you to keep each layout separately, so you can easily design each of them without the other controls getting in the way ;). The the code handling each of the layouts would also be separated. Then just drag those controls in the Form and use set their visibilities appropriately to show the one you want.
If none of those suggestions work for you, let me know, so I can look for other possible solutions.
It's more easy as you think, you just drag the panel's window upper, so will be outside of the form.
Use DrawMode: OwnerDrawFixed will hide TabPage header text DrawMode : OwnerDrawFixed
Another way to achieve the same (or similar) is: You can remove tabs from TabControl.TabPages collection and then add the tab you want to show.
During the Form initialization I remove tabs (so into the designer I can easily manage them) and in some control event (as button click) I show the tab the user has to see.
Something like that:
// During form load:
ctrTab.TabPages.Clear();
// ......
// During button click or some other event:
if(rbSend.Checked)
ctrTab.TabPages.Add(pgSend);
else
ctrTab.TabPages.Add(pgReceive);
In this way the user can still see the header tab but just as title of controls group, he can't change/switch the current active tab.

Communication between User Controls

I have a TabControl with two tabs. One tab has a list of stores and the other has a list of employees. On the store tab I have a button that displays all employees of the store; to do that, I want to switch to the other tab and invoke a showEmployeesFromStore(store_id store) method from that tab's User Control. How would I do that?
You've got the wrong mental model. Just because the user control isn't visible on the TabControl doesn't mean that the code is invisible as well. Just call the control's method in your code, it needs to be public of course. Then change the tab control's SelectedIndex property to switch the active tab page.
The button should not be part of the 1st user control. Actually it is better not to use a button but to just trigger an event when the user selects another store.
I would expose an event on the store user control for SelectedStoreChanged or something to that effect. Pass back the newly selected store_id in the event delegate.
Subscribe to that event with your form. When the event fires, it is the form's job to decide with to do with that information. In this case, have it pull out the store_id from the store UserControl's SelectedStoreChanged event and pass it in to EmployeeUserControl.showEmployeesFromStore(store_id store)
Keep your controls ignorant of each other. Let the owner of the controls decide how to react to whatever events are raised by the controls. You'll sleep better with dreams of increased usability, better separation of subject areas, and more fewer working weekends due to untangling odd control flow... ;o)
Just realized I missed a detail. The button you're talking about should be on the form itself and not any of the user controls, assuming you don't want it to just update in real time using eventing described above. On button click, the form should go check StoreUserControl.SelectedStoreID() and pass the result to EmployeeUserControl.showEmployeesFromStore()

How to create a copy/link of a user element in a tab control?

I have a .NET forms application using a tab control with several tabs. There are a few elements (a button and a few text boxes) that need to be displayed on every tab. Rather than create 5 seperate elements (including all the appropriate properties), is there a way to create "links" to one element?
For example, when an event occurs, I need a textbox to display the same information in each tab. As it stands, I need to create a new textbox for each tab, then explicitly write to each. It would be easiest to just write to one textbox, then consider the rest "links" which automatically update.
Those controls really ought to be somewhere else than on a TabPage. But you can get what you want by implementing the SelectedIndexChanged event and change the Parent of the control. This sample code keeps the text box on the selected tab:
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
textBox1.Parent = tabControl1.SelectedTab;
}
Sorry, there isn't any way to do this. controls on a form are childen of that form, they can't be simultaneously children of multiple forms. (a tab is basically a sub-form).
You could either create an array of references to all of the textboxes that you want to behave the same, and and write to all of them when you write to one of them. Or
keep the text in some location outside of the textbox, and update the textbox on the visible tab when ever the user changes tabs.

Can I have an 'offscreen' control?

I'm trying to create a DataGridView cell class which hosts a control (all the time, not just while editing). So far, my approach has been to add the control to the grid and try to synchronise its position with that of the cell.
Would it be possible instead to keep the cell offscreen, route mouse and keyboard events to it, and paint it onto the cell?
UPDATE: By 'offscreen', I don't mean that it should be added to another control such that it isn't displayed; I mean that it should never be added to another control at all.
You can create a control without adding it to the form, then using it as the Cell editor whenever you need to. Usually with grids, when you click on a cell to edit it, it's going to either create a new control and put it in the right place, or it's going to use an existing control. You can make this process a lot easier by creating your own custom cell / column types. See this MSDN page: http://msdn.microsoft.com/en-us/library/7fb61s43.aspx.
Most grids (including DataGridView and 3rd Party Grids) have a facility for adding custom cells.

Categories

Resources