I would like to know i have removed Application.EnableVisualStyles () as the program i develop for progress bar it will be easier if i remove that statement of "Application.EnableVisualStyles". The problem i face was, when i put datetimepicker i set the showupdown to true, the arrow in show up down does not display as formerly with the statement "Application.EnabledStyles". Is there a way i can solve it without addding "Application.EnableVisualStyles". Thanks
It is like this for the datetimepicker
enter image description here
i want like this for the datetimepicker with the enabled visual style removed
enter image description here
If you just want to use the old ProgressBar, this Hans Passant answer How do I disable visual styles for just one control, and not its children? shows how to turn visual styles off for a single control. I've adapted that code for your progress bar:
public class OldProgressBar : ProgressBar {
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appName, string idlist);
protected override void OnHandleCreated(EventArgs e) {
SetWindowTheme(this.Handle, "", "");
base.OnHandleCreated(e);
}
}
Now you can use Application.EnableVisualStyles(); and still use the old progress bar control.
Related
I'm making a dialog that look like Notepad's Find Dialog. I notice that the underline character of Notepad's Find dialog always show all the time (I have to press ALT key to see this with my dialog). How to always show underline character like that?
I try to use SendKeys.Send("%") on Form_Load event but nothing happens.
There is another problem, when I press ALT key on child Form, it show underline charater of parent Form too. How to avoid that?
This is sreenshot of Notepad's find dialog:
I pretty sure this is not about Ease of Acess Center, because the main Form of Notepad doesn't always show this.
Seeing the n in "Find" underlined in the Notepad dialog is an intentional bug. The dialog isn't actually part of Notepad, it built into Windows. Underlying winapi call is FindText(). The feature is in general a pile 'o bugs, one core problem is that creating a new window after the UI is put in the "show underlines" state doesn't work correctly, that new window isn't also in that state. Presumably the intentional bug was based on the assumption that the user would be somewhat likely to use the Alt key to get the dialog displayed. Yuck if he pressed Ctrl+F.
The Windows dialog probably does it by simply drawing the "Find" string with DrawText() with the DT_NOPREFIX option omitted. You could do the same with TextRenderer.DrawText(), omit the TextFormatFlags.HidePrefix option.
Not exactly WinFormsy, you'd favor a Label control instead of code. It is hackable, you'd have to intentionally send the message that puts the UI in the "show underlines" state for your own dialog. Do so in an override for the OnHandleCreated() method:
protected override void OnHandleCreated(EventArgs e) {
const int WM_UPDATEUISTATE = 0x0128;
base.OnHandleCreated(e);
SendMessage(this.label1.Handle, WM_UPDATEUISTATE, new IntPtr(0x30002), IntPtr.Zero);
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
Where "label1" is the control you want to show underlines. Repeat for other controls, if any. It is supposed to work by sending the message to the form, that this doesn't work is part of the pile 'o bugs. Yuck.
Fwiw: do not fix this by changing the system option as recommended in the duplicate. That's very unreasonable.
You can use RichTextBox control and extension method for that:
public static class FontHelper
{
public static void Underline(this RichTextBox txtBox, int underlineStart, int length)
{
if (underlineStart > 0)
{
txtBox.SelectionStart = underlineStart;
txtBox.SelectionLength = length;
txtBox.SelectionFont = new Font(txtBox.SelectionFont, FontStyle.Underline);
txtBox.SelectionLength = 0;
}
}
}
richTextBox1.Text = "Search for";
richTextBox1.Underline(7, 1); // index and length of underlying text
I have a TabControl with AutoScroll set to true on tabpages. The tabpage contains a RichTextBox, which is bigger in height that the page, so vertical scrollbar appears on a TabPage. If I scroll the page down and then click on the RichTextBox, the page scrolls back to top. Any ideas on how to prevent such behaviour?
UPD: Here is a sample project which can reproduce the issue. The issue occurs when the RichTextBox receives focus. E.g. scroll tabPage1 down, then select tabPage2, return to tabPage1 and click on the RichTextBox.
Well, after a bit of struggling I've finally found a solution here. All I had to do was to create my own class inherited from TabPage and override the ScrollToControl method, making it return DisplayRectangle.Location.
This happens due to the fact that once you select the richTextBox and it is "out of sight" it goes to the current position(which in your case is not visible or at the top). If you select the richTextBox first and then scroll you will avoid this. One way you can do this is to Select() the richTextBox on application start.
Add this:
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.Select();
}
EDIT:
You can also add the Select() on TabIndexChanged as the behavior will reoccur if you change Tabs.
The answer while correct was difficult for me to initially understand without seeing the code.
Perhaps this helps others.
public class CustomTabPage : System.Windows.Forms.TabPage
{
protected override System.Drawing.Point ScrollToControl(System.Windows.Forms.Control activeControl)
{
//return base.ScrollToControl(activeControl);
return activeControl.DisplayRectangle.Location;
}
}
After defining your custom tabpage class, inherit now from this class in your form with your TabControl.
private CustomTabPage tpJobSetup;
How can I change the selection color on a ListView? By default, when the user selects an item it shows a blue background. I want to change this to dark gray, or something...
Thanks for the help!
If you wanted your ListView to have the style of the Windows Explorer ListView (including the nice appearance with rounded edges in Win7/Vista), you could use a little P/Invoke to accomplish that:
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
internal static extern int SetWindowTheme(IntPtr hWnd, string appName, string partList);
// You can subclass ListView and override this method
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
SetWindowTheme(this.Handle, "explorer", null);
}
Well for WinForms you have to set the OwnerDraw property to true and then use the DrawItem and DrawSubItem events to draw the item manually.
See here for an example.
ObjectListView -- a wrapper around a WinForm ListView -- has properties to let you control the background and foreground color of the selected rows. It uses the technique that Obalix suggested, but it has already done the hard work for you.
So, with a little effort, you can produce something like this:
The "Feel Good Inc" row show a custom foreground and background for selection.
I have a winform app that we use in house. It has many individual controls on each of it's 25 "pages"(usercontrols). Our user base prefers very technicolor apps...they want a TextBox to be outlined Blue if it is a required field (color should go away if data entered). They want a TextBox to change to outlined Green if data has been changed in it to remind them to save. They want a currently highlighted TextBox to be outlined RedOrange.
I have been trying to come at this from many different angles (some of you have probably seen similar posts by me lately). Non of them work... So one way I KNOW will work is to register the paint event for every control and check for a "required" tag for the required portion. The OnFocus for the current field portion and finally the Validate event for the data changed portion.
I know this is not the best way or at least I STRONGLY suspect it isn't but I am out of time, nearly, and nearing my point of frustration. That being said, will that DESTROY my app's responsiveness? Is there a better way? Can I override the base control to color on different premises so that I don't have to go to each of the 100+ controls?
Any idea would be welcome because I am between my stupid Paint_Event idea and rewriting all the controls in WPF... :)
I will be rewarding a solution that works for me and that I can implement shortly with a Bounty.
I am so sick of colors...
Here is my attempt based on suggestions.
public class MyTextBox : TextBox
{
private bool _isRequired;
public bool isRequired
{
get
{
return _isRequired;
}
set
{
_isRequired = value;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (isRequired && base.Text.Equals(string.Empty))
{
HighlightControl(e.Graphics);
}
}
private void HighlightControl(Graphics graphics)
{
ControlPaint.DrawBorder(
graphics,
this.ClientRectangle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle);
}
}
I don't know the particulars of your app, but you could derive your own control from the base TextBox and let it handle much of this for you. Some thoughts:
Give it a bool Required property and some internal logic to color accordingly.
Have the textbox respond to its own
events - when text is entered, it can
do the right thing - change colors or
whatever is appropriate.
Provide your derived control with
properties to set the colors that get
used for each condition, then you can
switch them easily when the users
decide they want pink rather than
green.
You can utilize the focus events to "know" whether your TextBox (this is the one control you mentioned, so I'll assume this is the main control used here) has focus or lost it and the text change events can be used to drive all the color changes to the control.
You can certainly wire up all the
text boxes to control the
Apply/OK/whatever buttons to
determine if the buttons should be
enabled, assuming you have an Apply button or something like that which stores the data on click. There are a number of ways to communicate this. It's easy enough to iterate through the controls and ask their state.
Seems like this would work just fine.
What have you tried? You didn't really mention what you'd tried that didn't work.
You've got a problem, TextBox is, erm, special. Windows Forms leaves all painting to the native Windows EDITBOX control, the Paint event won't be raised. That can be fixed by setting the UserPaint control style to true:
using System;
using System.Drawing;
using System.Windows.Forms;
class MyTextBox : TextBox {
public MyTextBox() {
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
// Paint something
//...
}
}
Copy and paste this into a new class, compile and drop the new control from the top of the toolbox. Try it out, you'll be quite disappointed. What you see is the result of close to 20 years of appcompat hacks on a control that dates back to Windows version 2. One of the grave crimes that EDITBOX commits is painting itself without generating a WM_PAINT message. That was important way back when Windows had to run on a 386SUX, keeping it compatible with old programs prevented Microsoft from fixing its behavior.
No happy answers here, you'll have to give up on the idea of customizing the border. What you can do is give the control a distinct BackColor when it has the focus. For example:
class MyTextBox : TextBox {
Color mBackColor;
protected override void OnEnter(EventArgs e) {
mBackColor = base.BackColor;
base.BackColor = Color.AliceBlue;
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e) {
base.BackColor = mBackColor;
base.OnLeave(e);
}
}
You can inherit from base control classes and add your own drawing logic. That won't be very expensive performance-wise, but, if your app is of significant size, you'll have to replace each occurence of standard TextBox with your own implementation.
Is there any way to make a label on a .NET Windows form to be highlightable to allow for the text to be copied. I have attempted to do this with a text box that was made to look like a label, but this results in a flashing cursor.
I think this is pretty darn close:
textBox.BackColor = System.Drawing.SystemColors.Control;
textBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
textBox.ReadOnly = true;
textBox.Text = "This is selectable text";
textBox.MouseUp += new MouseEventHandler(
delegate(object sender, MouseEventArgs e)
{ HideCaret((sender as Control).Handle); });
[DllImport("User32.dll")]
static extern Boolean HideCaret(IntPtr hWnd);
And if you need it to span more than one line:
textBox.Multiline = true;
If you want it to be a predictable, well behaved and standard control with all the keyboard and shortcut support you simply need a textbox. And then the flashing cursor is a normal helpful feature, why fight it?
It's not unusual for selectable static text to show a flashing cursor. If you get the properties of any file in Windows Explorer and select any data in that window, you'll also see a flashing cursor.
I have done this previously, a couple of years back, I think I used this Win API call (but with a regular text box): http://www.dreamincode.net/forums/showtopic35107.htm
You have the HideCaret function in User32.dll. Use it like this:
[DllImport("User32.dll")]
static extern bool HideCaret(IntPtr hWnd);
private void textBox_Enter(object sender, EventArgs e)
{
HideCaret(textBox.Handle);
}
This will prevent the caret from showing when textbox has focus.
One thing to consider is to go ahead and use a label, but then programmatically copy content (the Label's text) into the clipboard using:
Clipboard.SetText(yourLabel.Text);