The wyDay blog is where you find all the latest news and tips about our existing products and new products to come.
If you've done any Windows Forms designing then you've undoubtedly used the LinkLabel control. You've also likely noticed its hideous look:
The ugliness of the LinkLabel that ships with Windows Forms is four fold.
The Windows.Forms LinkLabel looks as though the text was drawn to the screen once, then drawn again without erasing the first copy. This gives the LinkLabel a jagged, blocky look.
It was a simple bit of code. I used 'TextRenderer.DrawText(...)' to do the actual drawing. The hand cursor was simply a matter of intercepting the WM_SETCURSOR message to my LinkLabel2 control:
[DllImport("user32.dll")]
public static extern int LoadCursor(int hInstance, int lpCursorName); [DllImport("user32.dll")]
public static extern int SetCursor(int hCursor); protected override void WndProc(ref Message m)
{
//WM_SETCURSOR == 32
if (m.Msg == 32)
{
//IDC_HAND == 32649
SetCursor(LoadCursor(0, 32649)); //the message has been handled
m.Result = IntPtr.Zero;
return;
} base.WndProc(ref m);
}
SysLink is a link control added to ComCtl32.dll in Windows XP. So, why not use SysLink? Because SysLink doesn't exist in Windows 2000/98.
Maybe in 3 years, when Windows 2000 is dead, a simple SysLink wrapper for C# can be written.
It works with all the .NET 2.0 + languages (C#, VB.NET, etc.).
Also while you're at it download wyUpdate, or any of my other open source projects.
Go to the LinkLabel2 site for further updates.
Subscribe to our blog's RSS Feed or follow Wyatt (CEO of wyDay) on Mastodon (@wyatt@hachyderm.io) to keep up-to-date with our latest posts.
Nice work :)
Awesome, just what I was looking for.
Windows 2000 will never die!
</sarcasm>
Nice control and good alternative to the original LinkLabel.
But did you noticed that the WinForms LinkLabel control doesn't look always that ugly?
If the LinkArea properties doesn't cover the complete link text (e.g. you got the text "visit wyDay.com" and the LinkArea Start is set to 6 and the Length to 9 - so only "wyDay.com" is highlighted as link) you there's a nice text rendering - just like in your LinkLabel2 control.
Some preferences the original LinkLabel has is the ability to set a LinkArea and the different and the different link colors for active, visited and disabled.
Looks like there's no perfect LinkLabel control, yet. ;)
And if you take this comment as suggestion: Imo it really would be great to be able to set different Font properties for each link status. So you could underline the link in common state and remove underline in hover status or something else. Then the designer would have full control about the appearance. :)
The Windows.Forms LinkLabel is a better control for the developer customization.
As it is my control, LinkLabel2, has the colors hard-coded mainly as a placeholder for dynamically reading in the system colors (using a function like GetSysColor). Maybe I'll add properties too. Eventually.
Update: This has all been fixed. See the latest version.
Hi,
I'm having two issues with this control, maybe you can update it to fix it?
1) I can't seem to use a transparent background for the label which I kinda need it and without it, I can't use this control. My label is over a gradient image so... Is it possible to fix this?
2) How can I have the underline always on? Can't seem to find a property for it...
Hey Ricardo,
1) Yep, this is a bug. I've uploaded the fixed version (2.2).
2) Just set the Font property. Or at runtime you can use:
Hey,
Thanks for the quick reply and quick fix, but... Are you sure you fixed problem #1? Every time I select "transparent" as the background color I get an error saying the the property value is not valid
As for #2, the Font property doesn't allow to set italic (at least not with me) and I guess that could work at run time, but maybe proper support in the control without relying on run time could would be better? I mean, this is supposed to replace the LinkLabel control and by default, the LinkLabel is underlined. My best solution would be to change the "HoverUnderline" (instead of adding another property, which would be a more direct solution) to something else with 3 options "always underline", "underline on hover only", "don't underline", of course, with different and more professional names for the settings.
And since I'm suggesting this, wouldn't be good to have an AutoSize property just like the original LinkedLabel?
Make sure your app is referencing the newest LinkLabel2.dll. (Check the version number of the dll in your program's Debug/Release folders).
In musical terms I would say LinkLabel2 is more of a variation on a theme, rather than an improved rendition. It's a piece onto itself.
In other words: it's not a photocopy of Properties & Features of the LinkLabel.
You can adjust this at design time by clicking the ellipsis button ("...") on the Font property. The Font window will show and you can select the Font Style (Regular, Oblique, Bold, BoldOblique) and the Font Effect (Strikeout, Underline).
It was a design decision I made to not include the underline by default (just like the links on the wyDay website).
Nope. LinkLabel2 automagically adjusts its size when you change the text.
You're right, version 2.1 was still referenced... The problem was on Firefox's cache, I kept downloading 2.1 without knowing. It's fixed now.
Well, my suggestions were just to make it look and feel as close as possible to the original Windows Forms LinkLabel.
You may say it's a variation but in the end, it basically has the same name and does exactly what the original does, no more no less, it's just and improved control
Well, thanks for the support and it's on less problem for me to deal with :)
Keep up the good work.
Hi again,
I was fixing some stuff on my application and I've realized that this control really needs an AutoSize property like I've suggested before. I know the control "automagically adjusts its size" like you said but that's the problem. What if I want/need this behavior disabled?
Even though the control automatically adjusts it's size, there should be an option to turn that off. And that's exactly what the "AutoSize" property is for in the Windows Forms label controls. Although you're link label control adds a few features and fixes, you're also removing stuff...
Besides that, I also need to get back the "TextAlign" property that the original label controls have.
Ok, I'm going to explain why...
I need to have this label centered horizontally but the font face and size changes accordingly to the user OS. The only way to align a label like this is to change it's width to be equal the form width or make it wide enough, either way, the "auto size" must be disabled for this. Then, and since the label is very wide, I need to align the text in the middle somehow and that's what the "TextAlign" property does in the original label and linklabel controls.
I don't know if this is much work or not and if you are willing to update your control to reflect this but as I see it, these changes would just make LinkLabel2 more close to the original LinkLabel (which is what the developers expect) and I think they wouldn't mess with any of your additions/fixes.
Of course, I'm suggesting this because I need it, but also because I believe it would be correct choice. But it's up to you :)
Best regards
Hey Ricardo,
There are a few technical reasons why LinkLabel2 doesn't include things like AutoSize and TextAlign (and it's not just because I like being difficult :) ). It's because LinkLabel2 inherits from Windows.Forms.Control while MS's LinkLabel inherits from Windows.Forms.Label. The "Label" has the "TextAlign" and "AutoSize" properties, while "Control" does not.
Now, I know that's not the answer you were looking for, but I'd thought I'd give you a little background before I continue.
If they do end up messing with my code, I'll gladly add the changes to LinkLabel2. And if you end up ignoring my following advice you can always take a peek inside the "RefreshTextRect()" function. In particular the "Size = new Size(width, height);" line.
This isn't the only way to align controls; in fact it's probably the worst way.
Why it's bad news bears:
You've increased the size of "Paint" region to the width of the form. This means slower rendering (especially if you do this with many controls). Plus, every time your user resizes the form every control that uses this trick will Repaint.
How we align control in wyBuild:
Math. Math is fast - painting to screen is slow (very, very, very slow comparatively).
Or, to be more specific, we use the "Layout" event of the container control to move & size child controls.
How to center align controls the proper way:
You should use the Layout event of the immediate owner of the LinkLabel2 to reposition the control.
If the LinkLabel2 is in a ContainerControl use the Layout event for that ContainerControl. If it's directly on a Form, use the Layout event for the Form. I won't explain why here (do a bit of experimenting and you'll see why).
Then, from there, it's just a bit of math:
This way the LinkLabel2 isn't repainted on every resize. Saves time and makes your app feel snappier.
Yep, I was aware that LinkLabel2 derived from Control and not Label. I could change the source code and include that in my app but I didn't want to cause if you release a new version, I need to keep updating my version, which is boring lol.
About the resizing and stuff... I'm only using this ONCE and in an about box, which is fixed size, there will be no repainting whatsoever, so, that's not an issue in my application. The form is not that wide either, so it won't take that long to paint the label on the form. But this is just me and how I use the control (at least for now).
And it is the only to align the label IF I don't want to do it manually by code, that's what I was trying to say. Of course I can always handle the more appropriate event to see if the size changed and align it manually, but that's what I wanted to avoid.
But if that's the only way, I guess I have no choice...
Um...
While using that bit of code(the same as above, just converted to VB.NET):
I noticed that the cursor is not set back to default unless I set the cursor somewhere else (e.g. by hovering over the form).
Is there a simple way to fix this?
Nevermind, I came up with a quick and dirty workaround:
hoveringOverMediabutton is a boolean defined by me.
If it's true, a hand cursor is set, if it's false, the default (arrow) cursor is set.
Thanks for the initial code! :)
Excuse me for resurrecting a 2-year-old thread on a 4-year-old page!!!
After messing around with the original solution and taking a look at the [reflected LinkLabel source code][1], I "finally" found a quick yet clean way of doing it :
This class actually does what we want: It shows the proper system hand cursor without flickering and does this only on the LinkArea of the control.
[1]: http://reflector.webtropy.com/default.aspx/DotNET/DotNET/8@0/untmp/whidbey/REDBITS/ndp/fx/src/WinForms/Managed/System/WinForms/LinkLabel@cs/2/LinkLabel@cs
I do not even know how I ended up listed here, but I believed this post was excellent. I really don't know who you are but absolutely you are heading to a well-known blogger if you are not already ) Cheers!