How to draw on top of winforms controls with transparency? - winforms

I have an app with a bunch of controls in it and I want to place a set of cross hairs on top of it. My first attack used a PictureBox and ran into this problem. The solution that fellow proposes, seems a bit... verbose for what I need.
Is there a simple way draw on top of my form? Note that I don't even need the drawing to be part of a control as it doesn't need to do anything but just be there.

This eventually worked. I had to play some games though because most of the controls I wanted to draw on were not where it expected them to be.
Also, it ran into issues when controls were moved; it failed to redraw and stuff moved with the underlying control. This was fixed by forcing invalidation from the move event for anything that might move.

Does a PictureBox with a transparent image have the same problem as a Panel with BackColor set to Transparent? I'm thinking you could have a PictureBox with the crosshair image in it and move that around, instead of drawing it yourself...

Related

Why is there a black lag every time a WPF window is resized?

Other questions on SE address how to speed up nested UI control resizing, but- what if there aren't any controls?
As you drag the edge of a WPF window, even a main window with no content, black bars flicker briefly during the drag. This produces a crummy feel- one that I don't want to inflict on customers:
It does get slower and heavier with a full UI on top of it as well. This doesn't even get into how ugly it looks when resizing using the top or left edges. Windows Forms- even with the heaviest UI I've built- never looks this bad right off the bat.
What can be done to make WPF window resizing performance comparable to win forms?
(I have Windows 7 x64 and a triple monitor system on an AT Radeon HD 7470.)
You could update your graphic card and try it out again but that wont change anything. The reason is pretty simple. We all get to see this sometimes based how fast/slow our computer is. Sometimes it runs smooth because we do not have many visuals to draw. The reason is no proper background color is found in graphic card at that moment in redrawing process. Your drivers are fine, and its not just because you use Wpf. Other techniques use the same mechanism behind redrawing.
The first thing WPF will do is clear out the dirty region that is going to redraw. The purpose of dirty regions is to reduce the amount of pixels sent to the output merger stage of the GPU pipeline. Here is where we see the black color. Window itself at that point has no background color or its background color is set to transparent and so to us the GPU draws the black background. Things run async in wpf which is good so.
To fix this you could set a fix color such as "White" to the Window. Then the WPF system will clean out the dirty region but fill it automatically with white color instead of black. This usually helps.
Match the window color or the color of top most layer. Dont let GPU use black and you should do fine. Btw Wpf is faster than WinForm so dont worry.
The look is crummy indeed, especially when using the top or left border.
Which exact problem your screen shot is showing depends on how long your app is taking to render as well as a couple of background related settings that you might be able to tweak to get better resize. Plus part of the ugly resize is specific to Aero.
While I can't address the specific crazy slowness of WPF redraw, I can at least give some insight on why you see black, where that is coming from, and whether you can change to a less annoying fill-in color.
It turns out there are multiple different sources of the black and the bad resize behavior from different Windows versions that combine together. Please see this Q&A which explains what is going on and provides advice for what to do (again, not specific to making WPF faster but just seeing what you can do given the speed you have):
How to smooth ugly jitter/flicker/jumping when resizing windows, especially dragging left/top border (Win 7-10; bg, bitblt and DWM)?

Image glimmer or sparkle animation

I've been searching for awhile, but haven't been able to find anything. I'd like to be able to add kind of a glimmer or sparkly animation on an image element in wpf.
Essentially the effect here I'm after here is the same that you get with trading cards that are "foil's".
I'd like to have an image, and then be able to add this animation to it at will. I'm thinking maybe some kind of user control, or template possibly. Hopefully generic enough that I can just toss an image at it and it will just overlay the image and run.
Any ideas?
A simple construction that easily can be turned into a control is by nesting the image in a Grid and adding a second Grid (on top) as a sibling.
De second grid can be given a linear gradient brush that is primarily transparent but does contain a white glimmer.
This brush can be animated; you could move it and change the opacity of the grid/brush.
This way you do not change the image.

Winforms semi-transparent PNG over semi-transparent PNG

I think I must be missing something obvious, but I'm unable to find this after several hours of searching. Is there no way to use a PictureBox or other control to contain an image with partial transparent/alpha-blended pixels, and place that over another image and have the blending be based on the image under it?
For example, this produces the results I want:
Place a panel on a form.
Add an OnPaint handler.
In the OnPaint handler draw 1 PNG, then draw another PNG over it, using Graphics.DrawImage for both.
This does not:
Place a PictureBox on a form and set it to a PNG.
Place another PictureBox on the form and set it to a PNG.
Place the 2nd picture box over the first.
...even if the 2nd picture box is just empty and has a background color of Transparent, it still covers the picture below it.
I've read this stems from all winform controls being windows, so by nature they aren't transparent.
...but even the 15 year old platform I'm migrating from, Borland's VCL, had several windowless controls, so it's hard to imaging winforms doesn't at least have some easy solution?
My first example above is one answer, true, but that adds a lot of work when you can only use one big panel and draw all of your "controls" inside of it. Much nicer if you can have separate controls with separate mouse events/etc. Even if not an image control, and a control I have to draw myself, that would be fine, as long as I can just put one image in each control. In VCL they called this a "paint box", just a rectangle area you could place on a form and draw whatever you want on it. Has it's own mouse events, Bounds, etc. If you don't draw anything in it, it is like it's not even there (100% transparent) other than the fact it still gets mouse events, so can be used as a "hot spot" or "target" as well.
The PictureBox control supports transparency well, just set its BackColor property to Transparent. Which will make the pixels of its Parent visible as the background.
The rub is that the designer won't let you make the 2nd picture box a child of the 1st one. All you need is a wee bit of code in the constructor to re-parent it. And give it a new Location since that is relative from the parent. Like this:
public Form1() {
InitializeComponent();
pictureBox1.Controls.Add(pictureBox2);
pictureBox2.Location = new Point(0, 0);
pictureBox2.BackColor = Color.Transparent;
}
Don't hesitate to use OnPaint() btw.
Sorry, I just found this... once I decided to Google for "winforms transparent panel" instead of the searches I was doing before, the TransPictureBox example show seems to do exactly what I need:
Transparency Problem by Overlapped PictureBox's at C#
Looks like there are 2 parts to it:
Set WS_EX_TRANSPARENT for the window style
Override the "draw background" method (or optionally could probably make the control style Opaque).

Remove all extra space around a button with an image?

Alright, try as I might, I cannot for the life of me get rid of this tiny little border around my buttons.
Edit: I should mention, in case I didn't make it clear, these are buttons with an image on them, set to flat with the button sized to the image.
Images below:
Number one, I can't for the life of me get these borders to GO AWAY. I've checked everything I can think of. They're:
flat
border 0
no margins
no padding
manually sized to the size of the image (75px)
in a table layout where the columns are all:
manually sized to the width of the image (75px)
borderless
Nothing seems to really "work" to get rid of these. If I size the columns down to be 74px instead of 75px, most of them go away, but a few remain. I've triple and quadruple checked the images, and they don't have anything that I can pick up on that should be causing this... no transparency around the borders, definitely no border that looks like that.
Which leads me to the second problem:
Settings button when dialog is small...
Settings button when dialog is stretched out.
Settings button is also in the same table layout panel.
I've checked all the settings on the table layout panel as well.. I can't find any padding or margin or anything settings that suggest this should be happening.
Does anyone have any experience with this? What am I missing..?
Simple solution: using directly a PictureBox as if it was a button. You can change your image on mouse over or mouse click.
Have you tried a Toolbar/strip/whatever it's called these days? Probably not going to help as I believe it pads on your behalf, but worth a shot.
In the end you can toss the buttons in the trash and write your own control. A single control that manages N buttons will work well here.
I don't understand your second problem. What's the problem? It'll be fixed if you roll your own control anyhow.
While not a fix for the spacing issue, as a workaround you can make that gray gradient currently "behind" the "tabs" and control panel image into a BackgroundImage for the TableLayoutPanel using BackgroundImageLayout of Stretch. While not fixing the spacing issue, it would make it unnoticeable.
Writing a winforms control has its challenges (experience speaking here). I would agree that that is whats needed however. Depending on your project you may consider using XAML and WPF. It provides that fine detail you seem to be looking for in you application.
There are ways to host XAML controls in a winform app, but if you went this route it would be best to create a native WPF application. The reverse is also true (winform controls in a WPF app).
Did you check if the image has transparent pixels around the graphic pixels you want?
May be a simple crop solution.

WPF animation question

I am new to WPF in general and want to add some animation to my interface.
I have a label and an image. The label will fly in from the right side of the window, the image from the left. They'll meet in the center. The image will rotate while its flying in, while the text will pretty much just move across the screen.
So my question is. For this kind of animation do you get a path object where you can draw a line at design time and have elements move across this line at a certain speed?
In classic windows forms I would have approached the issue using a timer and then adjust the left property of the label at each tick. Surely WPF is more sophisticated than this though.
So can anyone tell me a good approach?
First: You need ExpressionBlend to create animation in WPF.
WPF is more sophisticated
Of course no, read about animation in WPF, Personally, I prefer video learning for it.
you can find here some clips, I recommend this series from Total training.

Resources