.NET Treeview doesn't send click event on empty control - c#

I'm working with a .NET Treeview control (not WPF, but regular winforms) and am having trouble with the right-click event (or any click event) not firing when the control has no nodes inside of it. As per the response to another thread on Stackoverflow, my event handler code is as follows:
private void tvTest_MouseClick(object sender, MouseEventArgs e)
{
// Note: this block below is needed so that the menu appears on
// the correct node when right-clicking.
if (e.Button == MouseButtons.Right)
{
tvTest.SelectedNode = tvTest.GetNodeAt(e.X, e.Y);
if (tvTest.SelectedNode != null)
{
tvTestContextMenuStrip.Show(tvTest, e.Location);
}
else
{
tvTestContextMenuStrip.Show(tvTest, tvTest.Location);
}
}
}
The problem comes in that while this works fine when nodes are present, if the control is empty, I can't right-click the control and choose "add a node" to add to the root. The handler isn't entered AT ALL, as I set a breakpoint right at the beginning, and it appears the method is never entered.
Does anybody know how to get "something" to happen when the Treeview is empty?

I was curious about this particlar problem you described so I created a new project then added a Treeview Control to the form.
I then created an event handler for the MouseDown event, and made it show a message, when the right button is pressed. If you need the code I am happy to provided upon request, based on the fact its about 2 lines and Visual Studio created the event method I don't see the point.

I don't think this was explicitly identified above, but the original poster implies that he's using MouseClick from his code:
private void tvTest_MouseClick
But the answer responds with an answer to use MouseDown:
I then created an event handler for the MouseDown event...
I was able to reproduce the original problem by using MouseClick. It seems as if MouseClick is only raised if clicking on a node, but the MouseDown is raised regardless of whether you are on a node or not - so you can choose one or the other depending on the behavior you want.

Related

Devexpress.XtraTreeList click node

I have a Devexpress.XtraTreeList component. I want to catch in click event where the user is clicked on expand button or the node? How can I understand this?
Edit: Actually I am trying to do something like outlook using treelist. When I click the node, for example inbox, the messages in inbox are shown right side on the screen. When the user click another node, the treelist must be updated because some messages may be read. I did this functions in click event. It ıs OK. But in this case expand buttons functionality does not working normally.
I found the solution..
Thanks everyone..
private void treeList1_Click(object sender, System.EventArgs e) {
DevExpress.XtraTreeList.TreeList tree = sender as DevExpress.XtraTreeList.TreeList;
DevExpress.XtraTreeList.TreeListHitInfo info = tree.CalcHitInfo(tree.PointToClient(MousePosition));
if(info.HitInfoType == DevExpress.XtraTreeList.HitInfoType.Cell)
... // your code is here
}
There is no event that fires when a Node is clicked. However, here are some other events that might interest you:
AfterExpand - Fires immediately after a Node has been expanded.
BeforeExpand - Fires before a Node is expanded.
FocusedNodeChanged - Fires immediately after changing the focused Node (which happens when the user selects a Node, regardless of whether they clicked on it or used an arrow key to get there).
I'll also note that DevExpress has their own knowledge base with examples and sample code. It would be a great place to start your research for future questions: http://www.devexpress.com/Support/Center/
private void xtraTree_AfterFocusNode(object sender, NodeEventArgs e)
{
}
You can handle the above event on the XtraTreeList control and then extract the Node that was clicked on from the NodeEventArgs - e.Node

ListView events set in the properties don't work

I am trying to use the MouseClick event from the properties of a listView to handle left and right mouse clicks.
Unfortunately the event never seems to fire. (Double clicked on the event to create a property, entered a bit of simple code and placed a breakpoint on the first line). The same is true of several other events listed in the properties (ItemSelectionChanged seems to work but the other events I have tried don't fire.
Here is the code added:
In form.designer.cs:
this.listView1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseClick);
In form.cs:
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
Some code
}
That method never gets called when I click on the listview. The listview is inside a tab on top of the stack.
I guess I am probably forgetting something very basic but what?
ListView is a bit unusual, its MouseClick event doesn't fire unless you click an item in the view. Workaround is to use the MouseDown or MouseUp event instead. You typically are much more interested in the ItemSelectionChanged event btw. You probably need its HitTest() method to see exactly what was clicked if you use MouseDown/Up.

Detecting a left button mouse click Winform

What I'm trying to do is get my winform to display a debug line when ever I click in my winform. However, when I do, nothing happens. I know how to get a button / other click event to happen. But what I need is to be able to click anywhere within my winform.
I've googled this for the past hour but can't see what I'm doing wrong. As far as I'm aware, this code should be correct in detecting a mouse click. This method is held withing the form1.cs class:
private void mouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
Trace.WriteLine("Mouse clicked");
}
I've tried setting brake points, but these don't get triggered either. What is it I'm doing wrong?
Sorry for the stupidly newbie question, but I am very new to winform programming.
How to add the EventHandler:
public Form1()
{
InitializeComponent();
// This line should you place in the InitializeComponent() method.
this.MouseClick += mouseClick;
}
Using the editor built-in to Visual Studio:
Go to the properties window (if you don't see it, press Alt + Enter).
Select the events icon (looks like lightning).
Double-click on the empty ComboBox to the right of Click.
You'll be taken to an empty method where you can put your code.
The method itself is correct. I think your actual problem is: you haven't added this method to MouseClick events.
In C# – and most other languages too – event is handled by an event handler. Windows forms and controls have events for all the events happening in your controls, such as OnClick or OnResize.
You can append methods to these events, and the methods will automatically get called when the actual event happens. Simply add the following line to your form's constructor, Form_Load-method, InitializeComponent-method, or such:
this.MouseClick += mouseClick;
Now when ever MouseClick event happens, your method mouseClick will be called automatically.
I would recommend reading Events C# Programming Guide. You need to add an event handler like so:
form1.MouseClick += mouseClick;

Change happens after 2 mouse clicks when it should happen after a single click

I have a c# windows form application where I have a treeView inside a tabPage of a tabControl which is a part of the main form.
For the tree view, I click on the items of the treeView which I want to select then some change happens based on my selected Items.
I am using the AfterSelect event for item selection and and the mouseUp event for undoing the selection.
The item selection and deselection happens right away with a single click (no problem). The other change with should happen based on the selected items happens after two clicks! A single click either on the item node or outside the node's area do not trigger this change. I have to click again in order to see the change. That is wired. I am not using mouse double click events for this or something similar, I am only using the events I described above.
How can this be happening? and How to resolve it? Thanks.
EDIT: I am using my own multi-selection version of the treeView and I found (using debug) that when I get the selected nodes of the tree in the AfterSelect event after the first click is zero, then it is the number of selected nodes with the second click. How come this is happening when selected nodes are added and to the current selectedNodes list with every click in the overrided OnAfterSelect event of the treeView?
here is part of tree view code:
public List<TreeNode> SelectedNodes
{
get
{
return selectedNodes;
}
set
{
removeSelectionFromNodes();
selectedNodes = value;
selectNodes();
}
}
protected override void OnAfterSelect(TreeViewEventArgs e)
{
base.OnAfterSelect(e);
base.SelectedNode = null;
List<MSTreeNode> nodes = new List<MSTreeNode>();
.
.
.
removeSelectionFromNodes();
selectedNodes.Clear();
selectedNodes.AddRange(nodes);
selectNodes();
}
Maybe Treeview is losing focus in between clicks (?). You could try setting Treeview HideSelection property to False to keep the currently selected item highlighted when the control loses focus.
I tried to use the MouseDown event instead of the AfterSelect event. I override it in the my own multi-selection version of the treeView and used in the c# application I am developing but still it did not work. I am not sure how mouse events really work. If not used carefully, you may see wired behaviors.
Well, I ended up overriding the MouseUp and MouseUp events in my treeView subclass then I created an event which listens for changes in the selectedNodes list. If a change to the selectedNodes happnes in any of the mouse events this event is triggered. Then, I used the ChangedSelectedNodes event handler of the treeview instance in my application to do the other changes when there is a change in the node selection. This time it worked as expected.
I posted this in hope that it would be beneficial to anyone else who ran into the same problem like me.
P.S. Sometimes things do not work as you expect them to be and you just have fight and go through every other possibility until you find the solution.
Disable the hide selection option and use afterSelect option
in my project that works well

How can a control handle a Mouse click outside of that control?

I'm writing a custom control and I'd like the control to switch from an editing state to it's normal state when a user clicks off of the control. I'm handling the LostFocus event and that helps when a user tabs away or if they click on to another control that's Focusable. But if they don't click on something Focusable, it won't switch out of it's editing state. So I have two solutions in mind:
Walk up the tree to the top most element when it goes in to an editing state and add a handler for MouseDownEvent (and handle "handled" events). In the handler I'd kick the control out of it's editing state and remove the handler from the top most element. This seems like a bit of a hack, but it would probably work well.
Example code:
private void RegisterTopMostParentMouseClickEvent()
{
_topMostParent = this.FindLastVisualAncestor<FrameworkElement>();
if ( _topMostParent == null )
return;
_topMostParent.AddHandler( Mouse.MouseDownEvent, new MouseButtonEventHandler( CustomControlMouseDownEvent ), true );
}
private void UnRegisterTopMostParentMouseClickEvent()
{
if ( _topMostParent == null )
return;
_topMostParent.RemoveHandler( Mouse.MouseDownEvent, new MouseButtonEventHandler( CustomControlMouseDownEvent ) );
_topMostParent = null;
}
Use Mouse.PreviewMouseDownOutsideCapturedElement and add a handler to my control. In the handler I'd kick the control out of it's editing state. But I don't seem to get the event to fire. When does the Mouse.PreviewMouseDownOutsideCapturedElement get kicked off?
Example code:
AddHandler( Mouse.PreviewMouseDownOutsideCapturedElementEvent, new MouseButtonEventHandler( EditableTextBlockPreviewMouseDownOutsideCapturedElementEvent ), true );
Just to clarify the answer provided about mouse focus - it was useful but I had to do some further digging + mucking about to get something that actually worked:
I was trying to implement something like a combobox and needed similar behaviour - to get the drop down to disapear when clicking on something else, without the control having knowledge of what something else was.
I had the following event for a drop down button:
private void ClickButton(object sender, RoutedEventArgs routedEventArgs)
{
//do stuff (eg activate drop down)
Mouse.Capture(this, CaptureMode.SubTree);
AddHandler();
}
The CaptureMode.SubTree means you only get events that are outside the control and any mouse activity in the control is passed through to things as normal. You dont have the option to provide this Enum in UIElement's CaptureMouse, this means you will get calls to HandleClickOutsideOfControl INSTEAD of calls to any child controls or other handlers within the control. This is the case even if you dont subscribe to the events they are using - full Mouse capture is a bit too much!
private void AddHandler()
{
AddHandler(Mouse.PreviewMouseDownOutsideCapturedElementEvent, new MouseButtonEventHandler(HandleClickOutsideOfControl), true);
}
You would also need to hang on to + remove the handler at the appropriate points but I've left that out here for the sake of clarity/brevity.
Finally in the handler you need to release the capture again.
private void HandleClickOutsideOfControl(object sender, MouseButtonEventArgs e)
{
//do stuff (eg close drop down)
ReleaseMouseCapture();
}
Capture the mouse.
When an object captures the mouse, all mouse related events are treated as if the object with mouse capture perform the event, even if the mouse pointer is over another object.
I usually get the parent window and add a preview handler, even if already handled. Sometimes when MouseCapture is not enough, this technique comes handy:
Window.GetWindow(this).AddHandler
(
UIElement.MouseDownEvent,
(MouseButtonEventHandler)TextBox_PreviewMouseDown,
true
);
I would approach this a different way - have the form that contains the control remove focus from the control when a user clicks on another part of the form.
Having the control actually loose focus is far cleaner than attempting to have the control "simulate" focus being lost in certain situations, when in fact it hasn't. Bear in mind that unless the control has really lost focus it will still accept things like keyboard input.

Categories

Resources