|
Hello !
Is there any way to detect if any of the controls inside a TableLaoutPanel is clicked ?
( I mean without using Click event for each control ).
I try using MouseClick's event of TableLayoutPanel , but this doesn't fire when a control is clicked.
Thank you !
modified 5-Apr-15 23:47pm.
|
|
|
|
|
You need to add an event handler which is connected to each control.
|
|
|
|
|
Ok , but what is going to handle this event ?
Because if he's going to handle the click action , this is the same as using all control's click event.
|
|
|
|
|
Yes. You have to wire up the Click event of each control to a central Click handler to do what you want.
It seems like your concern is based on the assumption that only one handler can be assigned to the Click event. That is NOT the case. Multiple handlers can be assigned to the same event and they will all get executed.
So, you CAN have your general Click event handler for every control that you want to be notified for and you can have individual Click handlers for each control for specific functionality for whatever a certain button, or whatever controls, is going to do when clicked.
|
|
|
|
|
sorry , but I have a central Click event.
The problem is that the code inside the click event is depending from the case where the click event is fired from user action ( so a user has clicked ) , or is fired from code.
I can't distinguish these 2 cases , then I ask if is possible to detect a click fro the TableLayoutPanel in general.
|
|
|
|
|
Again, the TableLayoutPanel is NOT a control you can click on. It is an extension to other controls where it adds properties to them to change the way they layout in their parent container, such as a Form or Panel.
There is no way to differentiate where a Click event came from. It's always going to be from the button itself.
If you're kicking off a Click event from code, you're doing it wrong. Move the code from inside the event handler into it's own method and call it from both your code and from the Click event handler.
|
|
|
|
|
What's the trouble with using all control's click event?
|
|
|
|
|
The problem is that the code inside the click event is depending from the case where the click event is fired from user action ( so a user has clicked ) , or is fired from code.
I can't distinguish these 2 cases , then I ask if is possible to detect a click fro the TableLayoutPanel in general.
|
|
|
|
|
I would say this is the point where you should ask yourself "why is this getting weird?" - and my answer would be "because a previous design decision was wrong/not optimal". I wouldn't trigger the Click-event programmatically. Instead I would move the code from the Click-Eventhandler into a separate method with a parameter that indicates whether it's being called from the Click-Eventhandler (= by a user-click) or from code:
SomeButton.Click += SomeButtonClicked;
void SomeButtonClicked(object sender, EventArgs e)
{
DoStuff(userClicked: true);
}
void SimulateButtonClick()
{
DoStuff(userClicked: false);
}
void DoStuff(bool userClicked)
{
if (userClicked)
else
}
|
|
|
|
|
Thank you , but the situation it's a little complicated and I can't use your solution.
I have another Event let's say Event2 that is fired when the button's click event is executed. But this event2 can be fired even without button's click event but from another action. And if this case is true , inside the event2 button's click event is called from code. So the events are depending to each other , and I can't find other way but only to distinguish that the click's event is fired by user click or by code.
|
|
|
|
|
I'm thinking , is possible that when I call the click event from code , to insert an special argment on its Args , and inside the click event to check this arg ?
Can this be done ?
|
|
|
|
|
Sure, either object sender or EventArgs e or both. I try to avoid doing that because I find it a bit messy but it'll work.
|
|
|
|
|
I don't want to change the sender because I need this. Can you explain to me , how can pass a special argument and to check on the code inside ?
|
|
|
|
|
Just derive your custom class from EventArgs that carries your custom arguments. Then check in the called eventhandler for the type of e and cast it to your custom class if it is the same.
|
|
|
|
|
Not very clear for me. Please could you write some code ?
Thank you !
|
|
|
|
|
Ehm. Yes. Just realized we're in the VB-Forum. Can you read C# ? Because I'm not good at writing VB
class MyEventArgs : EventArgs
{
public string Foo { get; private set; }
public MyEventArgs(string foo)
{
Foo = foo;
}
}
class MyButton : Button
{
public void SimulateClick(string foo)
{
base.OnClick(new MyEventArgs(foo));
}
}
void SomeEventhandler(object sender, EventArgs e)
{
if(e is MyEventArgs)
{
string foo = ((MyEventArgs)e).Foo;
}
else
{
}
}
|
|
|
|
|
Thank you , I understand your code.
But I have a last question :
Is it possible not to use your class , but this idea :
When I call the Button's click event from code , I use this instruction :
myButton_Click(myButton, EventArgs.Empty)
Now when this event is fired from a real user click , the EventsArg is empty or not ?
Because if is not empty , I can just test inside the click event , if eventArgs is empty or not ?
Can this idea work ?
Thank you !
|
|
|
|
|
You could do that. If the Click-Event comes from a real click, then e is of type MouseEventArgs. I would recommend using a custom class for two reasons: You can give it a name that explains its purpose so that your code will speak for itself. And if the need would arise to have a third cause for the event you would be out of options when testing if e equals EventArgs.Empty or not.
|
|
|
|
|
Hello !
I have a TablelayoutPanel with 1 row and some columns . I have added some controls on it.
The problem is that some controls are out of Maximum visible area of TableLayoutcontrol.
To resolve this problem I have added 2 special buttons that should perform Previous and Next. Between them , are the controls that I need.
Now how can I do that when I click the next button , to make hidden the first Control and to show anoher control before the Next Button.
For example :
< Control1 Control2 Control3 >
The user press the > button
< Control2 Control3 Control4 >
Thank you !
|
|
|
|
|
You need to reset the location properties of each control every time the left or right button is pressed. However, I would suggest that you would be better redesigning your form. Most users hate having to jump through hoops like this just to do their work.
|
|
|
|
|
The TableLayoutPanel isn't really a visible control. It's a kind of framework that add properties to the controls it "contains" and modifies the functionality of the layout properties of those controls.
If it were me that had to implement some kind of side-scrolling, I'd put the TableLayout and controls on a Panel control the width required to accommodate all of the controls, then stick that in another Panel that is the width of the viewable area and set it's AutoScroll property to True.
But, I wouldn't be doing something like this unless I absolutely had no other choice. It's a kludge design that makes your application a bit harder to use and visualize data.
|
|
|
|
|
Aren't Control1 .. Controln the buttons to select the result pages 1 .. n for your DataGridView? In that case I would suggest not creating n buttons but just three (or how many you want to show at maximum) and change their display-text and click-"interpretation" dynamically. So after a click on next, Control1 will change its displayed text from 1 to 2 and when clicked would trigger page 2 to be shown instead of page 1, etc.
|
|
|
|
|
sorry , but these are not buttons. this question is not related with my previous questions. These are different controls( Most of them are TextBox and Combobox )
|
|
|
|
|
Alright, nevermind then
But I have to agree with Richard and Dave - I wouldn't recommend doing that. Wouldn't it be possible to just show all controls at once?
|
|
|
|
|
The following code is supposed to redirect the call to the Excel Calculate Method to my own function (MeMsg)
After running the HookCOMFunction routine , the Test Macro successfully executes the MeMsg replacement function as expected .. So far so good
However, when executing an excel calculation via the User Interface (not via code) such as by pressing the F9 key , the MeMsg replacement function doesn't get called ... I thought that replacing the 'Calculate' VTable offset address with the address of my replacement function would also work everytime excel is calculated via the User Interface
Any thoughts anyone ? My goal is to hook the excel Calculate Method via code as well as via the UI
Regards.
Code :
Option Explicit
Private Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As Long _
)
Private Declare Function VirtualProtect Lib "kernel32.dll" ( _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal flNewProtect As Long, _
lpflOldProtect As Long _
) As Long
Private Const PAGE_EXECUTE_READWRITE As Long = &H40&
Sub HookCOMFunction()
Dim pVTable As Long
Const lFuncOffset As Long = 84
CopyMemory pVTable, ByVal ObjPtr(Application), 4
VirtualProtect pVTable + lFuncOffset, 4&, PAGE_EXECUTE_READWRITE, 0&
CopyMemory ByVal pVTable + lFuncOffset, AddressOf MeMsg, 4
End Sub
Private Function MeMsg(ByVal voObjPtr As Long, ByVal Param As Long) As Long
MsgBox "Excel 'Calculate Method Hooked !!"
End Function
Sub Test()
Application.Calculate
End Sub
|
|
|
|