I have controls in the same place (one on top of the other)
Is there a way to get an event when the z-order changes?
The purpose is for debugging to see when and who change the order
It can be changed by BringToFront or SendToBack or SetChildIndex
Like Control.ZOrderChanged or form.Controls.ZOrderChanged
Changing the ChildIndex will trigger a Layout Event on the control that is parent to the child control. Of course this assumes that SuspendLayout has not been called on the parent control.
You can filter the event by checking the LayoutEventArgs.AffectedProperty Property (a string) to see if it is equal to "ChildIndex". To determine which control triggered the event, check the LayoutEventArgs.AffectedControl Property
Related
I have a UserControl in my WinForms project. I add some objects of this UserControl to a FlowLayoutPanel at run time using code.
I want when I add my first UserControl to FlowLayoutPanel, change its BackColor.
Is there any event for the UserControl to aware when add it to a parent control(something like UserControlAddedToParent)?
it seems that you are looking for Control.ParentChanged event
This event is raised if the Parent property is changed by either a programmatic modification or user interaction
I have a long form with a bunch of CheckBox's and occasionally some TextBox inputs. I want an event to be raised any time any control is changed (i.e., any CheckBox state is changed or any TextBox.Text is altered). Is there a global way to do this without having to add an event handler to each and every control?
One of the advantages of WPF and its declarative nature is that events are inherited down the visual tree.
<Window x:Class="MyApplication.MainWindow"
....
TextBox.TextChanged="TextBox_TextChanged" CheckBox.Checked="CheckBox_Checked">
All TextBox and CheckBox controls will inherit these event handlers. The same approach can be taken in other controls such as Grid so only the controls within the Grid are affected.
One way do this would be to subclass the CheckBox and TextBox classes and implement the required handlers in those classes.
You will still need to go through your application and replace the standard CheckBox and TextBox with your classes.
You can use TextBoxBase.TextChanged="MainWindow_OnTextChanged" on window or user control.
There are so called class events in WPF. Put this in the form's constructor:
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.TextChangedEvent,
new RoutedEventHandler(AnyTextBox_OnTextChanged));
This way you register a handler to TextChanged event of all text boxes. Similarly with check boxes:
EventManager.RegisterClassHandler(typeof(CheckBox), CheckBox.CheckedEvent,
new RoutedEventHandler(AnyCheckBox_OnChecked));
I've several controls in the same canvas and may one be covered by another. They are all with same zIndex, but for the order loaded, some being up and others down.
My Question if Acontrol is over Bcontrol, and I click on them, but only A gets the click event. How can I make B get the event, too? Thanks.
If you only wanted the one in the back to get the event, then for all the controls in front of the first one, you have to set IsHitTestVisible = False for the one behind to get the event - but this isn't what you want.
If you want them all to get the event think of the entire UI as a tree of elements. All of these controls you're talking about are siblings. When something is clicked, the parent is the first to get notified, and if it doesn't handle the click, it gets passed down to the visible child element of that parent at that mouse position, and so on until it's handled. Your only way to stop the child that gets clicked from handling the mouse click is to have the common parent of all the siblings handle the event first.
You will then have to do something clever in the parent's handler to invoke the click event of all child elements that can be found beneath the mouse - the problem is that whereas the framework used to do the hard work of determining which control was under the mouse, you will will now have to do that hard work.
No chance. Even if you mark MouseClick as unhandled it will route to parent element (Canvas) not sibling. The only way is hit-testing. When the user click on Acontrol you should hit-test to determine whether another control is under it.
You must use hit-test with callbacks. This one allows you to skip Acontrol in order to find Bcontrol. If you find it, you can treat Bcontrol as clicked.
I have FlowLayoutPanel and UserControl's on it with drag & drop reordering. This sort of works. But the problem is that child controls prevent dragging of the actual parent UserControl.
So my question is how to enable dragging of a UserControl that contains child controls?
If I understand you right I had the same problem as you and I solved it by propagating events of the child element to it's parent.
If you have a draggable UserControl containing a label. You have to call the events of the UserControl when the events of the label occurs. E.g. in the Label's OnMouseDown() call the UserControl's OnMouseDown() and just pass the Event-Args. I didn't find a better way than handling each event that is required for drag and drop separately.
I have 2 grids. When user is doing edits in one grid, I want to disable the other grid from getting focus, or atleast other grid from changing its foccussed row.
Example:
Parent grid, children grid.
If user is making edit in children of particular parent. I want to prevent user from suddenly shifting focus to different parent row. how to do that ?
The only ways you can prevent a control receiving focus is to change it's Enabled or Visible properties.
Simply changing the parent's Enabled property to "false" (e.g. for the CellBeginEdit) and then back to "true" (e.g. in the CellEndEdit event) will prevent the user from selecting a new parent row.
There are a lot of ways to do this but thats how I would do it (just a concept so ignore if any property does not match):
Create a property called mode and then use enumeration to set it to Edit or None etc.
Suppose you have GridViewParent and GridViewChild. In the FocusedRow event of child grid, at the start of all code, set the value of mode to Edit and at the end of all code in the event set it to None.
Then in the FocusedRow event of parent grid check whether the mode value is edit or not, if it is edit then use e.Cancel or something to get out of the focused event of the parent.
Now if you let me know exactly which grid are you using I might send you the code.