Notification from parent to child that the position was changed - c#

I have a custom control that needs to be informed of layout changes from the parent. So if the parent relayouts the child, i want to calculate the new visual position. Unfortunately ArrangeOverride on the child won't get called, which makes sense, because the position doesn't really change inside the child control. Now in the layout pass, my custom control gets properly positioned but the ArrangeOverride is not called.
To give you a clearer picture of what i'm trying to achieve: I have a control, that blurs the background giving an aero glass like effect. To achieve that, my control renders a background control into a visual brush and calculates the viewbox for that brush to make the background shine through, which then is blurred via a blur effect. Its working perfectly fine, as long as the layout doesn't change. If it does, i need to update the brush. And i did this inside the ArrangeOverride method.
So i tried to use ArrangeOverride, MeasureOverride, various combinations of Invalidating or Parent invalidating. At first i inherited from ContentControl but changed that to Decorator, thinking that the Decorator might have some special behavior to no use. I want to avoid LayoutChanged as much as possible because its a very very evil event. I would give you some code, but there is nothing special about it and i think its a rather fundamental problem not really bound to my code. The layouter by the way can be anything(not only canvas).
So what event, methods or ways do i have to get informed of the parent telling my control "I know you didn't changed anything, but i did repositioned you".

So i fixed it in a way i'm not very happy about, but it resolved alot of other unecessary stuff just to make it work, like when the blur control itself is animated. So this solution works now with whatever happens. While i avoided the LayoutUpdated event, i used a similar "evil" event. CompositionTarget.Rendering so in the Loaded event, i register to the rendering event, in the Unloaded i unregister from the rendering event. That way it doesn't matter how often Loaded or Unloaded gets called. In the rendering event itself i just trigger my VisualBrush.Viewbox invalidation code. This works perfectly fine, even if though the event is fired alot. I don't use the blur that much so it doesn't impact the performance so much ... for now.

Related

Prevent background scrolling up by soft keyboard

How can i prevent scrolling up the background image of the page? The rest content should scrolling like always
You can handle the InputPane.Showing and InputPane.Hiding events to override the content scrolling as you'd like. By default, the InputPane will apply a translation to the entire page to keep the focused control in view, but you can handle this yourself for custom behaviour.
For your case, you can find the space the InputPane will take from the OccludedRect property, do the math to figure out how far (if at all) you need to move the page to keep the focused control visible, and apply a transform to a control container rather than to the entire page. Set the EnsuredFocusedElementInView property to indicate that you did the sliding so the InputPane doesn't do its own.
Another option would be to handle Showing and apply an inverse transform just to the image, but it will be trickier to figure out how far the InputPane moved things than it will be to just move them yourself.

Drawing Custom Control above all other controls (previously added)

I have a UserControl that adds other UserControls, but I want the "latest" control added to be topmost so it's above the others. Because the controls should be overlapping eachother. Like a card game. So I add 5 controls, the first one should have the least priority the latest the most priority - most visible.
Any ideas?
Or do I have to override the Paint method for the "container" control? And Control.CreateGraphics() and draw it?
Consider BringToFront and SendToBack methods of the Control class.
Check out answers to these questions too
How to set Z-order of a Control using WinForms
Bring Winforms control to front
Just use userControl1.BringToFront() when you add the new control.
Note however, that won't prevent the user from "tabbing" into the controls that are underneath it. For that, you need to disable or make invisible the other controls.
In Windows Forms, the order in which controls are added to their parents' Controls collection determines the order of their rendering.
This means that either you handle the addition of child controls in code and use the appropriate insert positions, or you move the controls around in the designer (which, unfortunately, often means dangerous hand edits to the *.Designer.cs file).
I recommend that you go for the first approach, which is the only feasible method for larger WinForms projects anyway, and make the control insertion logic explicit in your code. The good news, by the way, is that there is no need to tinker with paint handlers, so your worry about hacks like using CreateGraphics() is unjustified and dispelled :)

Owner-Drawn ToolStripDropDownButton

I'm writing some custom behavior for a ToolStripDropDown control. I'd also like to modify the ToolStripDropDownButton itself to display a colored shape.
I see that I can handle the Paint event and draw whatever I like. However, is there any way to have the button paint the default background before I paint the shape? It would be hard to get the background exactly right, especially with future versions of .NET and Windows.
In plain ol' Windows, I could invoke the default proc handler before or after my paint code. I'm not seeing any way to accomplish that in .NET. Or perhaps there's a way to tell the button to paint only the background?
When you handle the Paint event (as opposed to overriding the OnPaint method in a derived class) the base class (default proc handler) is already getting called. Everything gets drawn as normal, and then you're essentially drawing on top of that in the Paint event. You can see that clearly here:
The trick is making sure that you leave enough of the control's clipping rectangle exposed to show the part you want. The e.ClipRectangle property retrieves the entire button's client area, so if you just
fill that with a color swatch, you're going to cover up the drop-down arrow and default background, too. The above demonstration was created using the following ugly sample code:
private void ToolStripDropDownButton1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Chartreuse,
e.ClipRectangle.X + 3, e.ClipRectangle.Y + 3,
e.ClipRectangle.Width - 12,
e.ClipRectangle.Height - 12);
}
Other than that, I don't think there's a way to customize what exactly gets drawn by the base class. Owner-drawing (at least in WinForms) tends to be an all-or-nothing affair. You get complete control,
but it comes at the price of having to implement everything yourself.
Of course, in case you haven't already noticed, the ToolStrip control already doesn't look like a native Windows control. And even worse, it is always going to look exactly the same as it does now,
even in future versions of Windows that completely overhaul the UI. (The MenuStrip is plagued by
this same phenomenon, and the difference is very visible in Windows Vista/7 where the standard API menus have changed dramatically). The reason is that both controls are drawn entirely in C# code written in their WinForms implementations. Personally, I think it looks ridiculously cheesy, and wouldn't use it in one of my applications on a bet.
You can assign a custom renderer that uses the UxTheme API to draw the buttons, which will get much closer to approximating the look of the native menus and toolbars. A pretty thorough sample is available here. I've written something very similar for the WinForms development that I've done requiring the additional features of the ToolStrip class (such as embedding combo boxes) not offered by the
old-school MainMenu and ToolBar controls that simply wrap their Windows API equivalents. By choosing to do things this way, you do have more control over exactly what parts of the base class renderer you wish to call, as you've written the code explicitly yourself. Highly recommended if you're
the type that cares at all about UI, native feel, or user experience.

Winforms: creating a dynamic timeline control

I need to create a winforms control what looks something like this:
Currently i'm considering taking a picturebox/panel and overriding onpaint event and drawing all the stuff myself. But somehow this approach doesn't seem right.
I was wondering maybe there's an easier way out or perhaps a better solution?
How would you make a control like this?
No, that is the right way to do it. Trying to use something like a TableLayoutPanel is not only excruciatingly painful, it also sucks serious mud taking a second or more to paint itself. It will take a bunch of code, but it isn't hard code. Plenty of for loop opportunities as well.
Get the scrolling view with panel's AutoScrollMinSize. Use Graphics.TranslateTransform() passing AutoScrollPosition in the Paint event or OnPaint override. The latter is recommended, derive your own control from Panel to keep the code separate. You have lots of flexibility here to customize the appearance, have fun.
The last time I did something like this I did the grid as a bitmap, loaded the image into a picture box, and drew directly on the image. The problem with using the paint event it's not persistent with minimizing etc unless you keep redrawing it.
It would probably be easier to override a literal control or inherit from the CompositeControl class and then render it with HTML (tables) and Javascript as opposed to drawing it.

Can i change the color of the tooltip displayed form Treeview

My code to display tooltip on mousehover is as follows
e.Node.ToolTipText = Convert.ToString(sb);
But this is displaying with the default color yellow. Can i change this to some other color. I did not find any property for that . If possible can any one give me an idea...
Thanks & Regards,
M.Dorababu.
The background color for a tool tip is a system color setting, you cannot reasonably change that setting. You can alter the appearance yourself by setting the ToolTip.DrawMode property. A good example of the Draw event handler you'll need is in the MSDN library topic for that event.
The next obstacle is definitely the harder one. The tooltip control that displays tips for nodes is built into the native Windows control, you cannot replace it. You'll have to give up on the TreeNode.ToolTipText property and store it elsewhere. Like the Tag property, or generate it on-the-fly.
Then you need to wire into the TreeView's MouseMove event and use its HitTest() method to find out where the mouse is located. Toggle a Timer's Enabled property when the mouse is moved. Use the Tick event to call the ToolTip.Show() method. And wire MouseLeave to turn everything off.
Quite possible, falls in the "when there's a will, there's a way" category.
There is no standard property for that. And for good reason: The colour of the tooltip is none of your business, it’s up to the user. If you really want to work against established practices and reduce the quality of your software for no reason other than to be different, then you’ll have to create your own tooltip component. Otherwise, you should stick with the default.

Categories