Transparent pixels aren't transparent - c#

Let me start off by saying I tried to research this, but I'm unable to word it to where I wouldn't get irrelevant results.
So here's the issue. I have a button (actually, 6 buttons) which have a rounded corner appearance. They're saved as PNGs, and loaded into the button using button.BackgroundImage = [resource]. Five of them work perfectly fine. When they're clicked, the background image is changed and, again, looks fine - including changing back when the button is no longer pressed. Then there's the button in the screenshot below.
I have no clue where this green color is coming from - in fact, when I go pixel-by-pixel over the image using GetPixel, and check the ARGB values, they turn out to be purples with A = 0. Also confusing is that the green only shows up at run-time -- as shown in the image. According to PhotoShop and GiMP, the RGB is 46,139,86 .. GetPixel shows them to be various colors in the purple range, but as an example, at 0,0 it shows 164,119,182 A:0.
Here's the list of things I've tried (some pseudocode):
if (pixel.A == 0) { SetPixel(x,y,Color.Transparent); } -- No change
if (pixel.A == 0) { SetPixel(x,y,Form1.TransparencyKey); } -- See
through to desktop instead of form background (as expected).
Use a known good image (see screenshot) -- No change.
Delete control, copy and paste a known good control (see screenshot)
-- No change.
Add another control, hoping I could hide the flawed one and basically
just ignore it. -- All new buttons have this issue.
Move button to different area of form (long story). -- No change.
Set no background in designer, then set the background in Form1.Load. -- No
change.
Restart Visual Studio. -- No change.
Clean solution, rebuild. -- No change.
Restart computer. -- No change.
Anyone have this issue before, or know what's going on? I have a solution that works (use a panel as a button - I just tested it and the transparency is fine on a new panel) .. but I'd prefer to figure this out. Thanks in advance!
Here's the imgur:

Related

Editing UINavigationBar translucence adds padding on bottom

I've been developing with Xamarin and iOS for about two weeks now, and currently I'm attempting to figure out why a strange bug is happening. I've looked all over Google and even SO, but can't find an answer...one that works, anyways. As the title says, whenever I change the Translucent boolean property of my NavigationController.NavigationBar, extra padding is added for seemingly no reason. This can be seen in the image below:
The line of code I use for this is this.NavigationController.NavigationBar.Translucent = false; and without that line, the application looks like this:
Other than that line, the NavigationController.NavigationBar is unedited. So, does anyone know what I'm doing wrong? Any help would be much appreciated...thanks SO!
It depends on the way how you construct your views and their containments.
Make sure that EdgesForExtendedLayout (Apple Docu) has the right value. I would suggest UIRectEdge.All.
In the case you are using a scrollView als check the automaticallyAdjustsScrollViewInsets property.
So, I actually figured out through posting on the Xamarin Forums and browsing through their documentation that the UINavigationBar.Translucent property adjusts the view if you turn it off such that all of the screen's contents are visible beneath the now-opaque UINavigationBar. I was simply placing the UI elements with unnecessarily large Y-values because I was unaware of the screen change after .Translucent = false;
I changed the .Frame = new CGRect(x, y, w, h) properties of each UI element with respect to 0 being right below the navigation bar, not underneath it.

How can I set the cursor to the arrow-with-plus-sign on a winforms app?

This is the cursor I want to use. It has a little plus sign below the arrow:
When I try to set the current cursor in my Windows Forms app, I do this (and it works):
Cursor.Current = Cursors.WhateverCursor;
The available cursors can be seen here. Notably, I do not see one like I want.
How can I get that little plus sign cursor?
This is the list again, in case that link dies:
AppStarting
Arrow
Cross
Default
Hand
Help
HSplit
IBeam
No
NoMove2D
NoMoveHoriz
NoMoveVert
PanEast
PanNE
PanNorth
PanNW
PanSE
PanSouth
PanSW
PanWest
SizeAll
SizeNESW
SizeNS
SizeNWSE
SizeWE
UpArrow
VSplit
WaitCursor
The system cursors only get you so far. For more you need to use an external resource..
You should create a proper cursor file (somefile.cur) and then assign it to the current cursor:
Cursor myCursor = new Cursor(yourCursorfile);
Cursor = myCursor;
To create it do use a nice application; I found Greenfish to work OK (although their own icon looks like crap ;-)
Make sure to avoid colors, as the above code won't work with colors, afaik.
Here is an example I used in one of my projects..
If you want to use it for a drag and drop operation (which is generally where this kind of cursor shows up) check out DragDropEffects, I think that's what you're looking for.

Hide or change the "no data in local tile cache" message in GMap.NET

I'm using GMap.NET. When zooming too much on the map and no image is available for the zone, a exception square prints on the map. This is OK, I don't want to change the behavior. I just want to make up the GmapControl, and I'm almost done. All I need now is changing or removing the exception message : "Exception : no data in local tile cache". But I can't find the right property...
For people interested in, I've asked on the GMAP official topic, and I had some interesting answers, except for this one part : http://greatmaps.codeplex.com/discussions/389159
As already mentioned in http://greatmaps.codeplex.com/discussions/389159, I embarked on a similar mission:
mapControl.EmptytileBrush = new SolidBrush(Color.Gainsboro);
mapControl.EmptyTileText = String.Empty;
mapControl.EmptyTileBorders = new Pen(Color.Gray);
However, GMap exposes no property to hide the exception text, and after removing the offending DrawString inside (GMAP v1.6, line 753 of GMapControl.cs), I recompiled and found that the binaries were not the same as the source!
The recompiled source, now does not display the exception text at all (when using cached mode only).
As a result - all that was necessary in my case was a rebuild or Core and WinForms.
When zooming in, GMAP now uses previous map data as far as possible, then eventually draws a blank white tile by default when the zoom is about 10 levels lower than the previously available level.
This behavior is acceptable - after all, who except for a debugger/developer would want to see bright exception text instead of a blank image? :)

make Label control text look as good as it does in VS form designer

In VS2008 I designed a form for a C# dll. The dll is a plugin for a somewhat older app (ca. 2005): let's call it "OldApp". In VS form designer, the text in Label controls on my form is nicely rendered: antialiased and properly kerned. But when I bring up this form within OldApp (where the C# dll runs as a plugin), the text in Label controls looks ugly. It's legible, but the kerning is poor: the letters are spaced further apart and at seemingly random offsets. Anything I can do to make the text labels from within OldApp look as good as they do in VS's form designer? I doubt the specific font matters, but it's Arial, 7.2 pt (VS2008 default). I tried playing with the two relevant lines in Program.cs (see below), to no effect.
Application.EnableVisualStyles(); // tried using it and commenting it out
Application.SetCompatibleTextRenderingDefault(true); // tried true and false
I found a similar problem on MSDN forums that mentions adding the following line after the EnableVisualStyles() method.
Application.DoEvents()
Seems to be a bug in older .NET versions...which version are you using?
After an investigation I have some findings, so I'll just answer my own question:
The bad news: the old-style text rendering used by OldApp is what's causing the problem. I verified it by toggling the UseCompatibleTextRendering property for the label control in VS. The font distortion I see is the same one I see in OldApp. Which means that the Application.SetCompatibleTextRenderingDefault(false) line in my code has no effect. OldApp will ignore it and do old-style rendering anyway.
As suggested by DeviantSeev using a bigger font helps a bit. It doesn't get rid of the bad kerning, it just makes it less noticeable. I increased the font from 7.2pt to 8pt only (not 12pt), because the dialog box becomes too big otherwise. The way to do this is in the form's Font property (not the control's). This way, you'll change all controls uniformly (if their Font property is set to default).
The font sizes in VS appear to be discrete rather than continuous, or maybe there's an int() rounding off involved. Increasing the font from 7.2pt to 7.4pt results in very little change, while at 7.5pt the font makes a sudden jump in size.
Forms have an AutoScaleMode property. If it's set to Font and the form is resizeable, the form will resize in VS in proportion to the change in font size. This way, in VS you can find an acceptable middle ground between a (legible) font size and a bloated dialog. However, be careful: the auto-scale operation can suddenly go awry, for example if you change the Font units from points to pixels, inches, etc. You may suddenly end up with microscopic controls or a form bigger than your screen and hitting undo won't fix it. You really don't want to re-design your form again, so save it before any font unit change and then again when you're happy with what you see.

Partial transparency with C# .NET 3.5 WinForms?

I'm making a .NET 3.5 app with a form that draws a partially transparent black background. I'm overriding OnPaintBackground to accomplish this:
protected override void OnPaintBackground( PaintEventArgs e )
{
using ( Brush brush = new SolidBrush( Color.FromArgb( 155, Color.Black ) ) )
{
e.Graphics.FillRectangle( brush, e.ClipRectangle );
}
}
It works, but occasionally the form draws over itself without clearing the screen, making the transparency darker than it should be. I've tried playing with Graphics.Flush() and Graphics.Clear(), but it either doesn't help or completely removes transparency. Any suggestions?
Edit:
Here's what it looks like, after starting the app on the left, and after the form redraws itself a few times (in response to tabbing from one control to another) on the right:
Transparency Issue http://www.quicksnapper.com/files/5085/17725729384A10347269148_m.png
Edit 2:
I was trying a few things out this morning and noticed that when the desktop behind the transparent portions change, it's not actually being redrawn. For example, if I open Task Manager and put it behind the window, you don't see it refreshing itself. This makes sense with what I've been seeing with the transparency levels. Is there a function to make Windows redraw the area behind your window?
Edit 3:
I've tried changing a few properties on the form, but they all result in the form drawing non-transparent black:
this.AllowTransparency = true;
this.DoubleBuffered = true;
this.Opacity = .99;
I'm going to try creating a separate window for the transparent portion as overslacked mentioned, but any other ideas are still welcome.
I think I would call this expected behavior, actually. What I would do is render my background to an in-memory bitmap and, in the paint event, copy that to the form (basic double-buffering).
If I'm way off base, could you post a screenshot? I don't know that I'm imagining what you're describing correctly.
EDIT:
I'm wondering about your use of OnPaintBackground... pre-.NET, if you were doing double-buffering you'd catch and ignore the WM_ERASKBKGND message (to prevent flicker), render your image to an offscreen buffer, and copy from the buffer to the screen on WM_PAINT. So, try changing from the OnPaintBackground to OnPaint.
I haven't done too much of this kind of thing in .NET, but I had a pretty good handle on it before; I just don't know if it'll translate well or not!
EDIT 2:
Marc, the more I think about what you're trying to do, the more problems appear. I was going to suggest creating a background thread dedicated to capturing the screen and rendering it darkened; however, in order to remove your own form you'd have to set the visibility to false which would create other problems....
If you're unwilling to give up, I would suggest creating two windows and "binding" them together. Create a semi-opaque window (by setting opacity) for your background window, and create a second "normal" window for the foreground. Use SetWindowRgn on the foreground window to cut away the background and position them on top of each other.
Good luck!
Is Graphics.CompositingMode set to CompositingMode.SourceCopy? That should cause painting the background twice to be equivalent to painting it once, since it will replace the existing alpha/color data instead of compositing over it.

Categories

Resources