How do you remove the dotted line that appears on buttons when they are selected (either via tab or by clicking them)?
This question is for winforms - any help is appreciated.
Edit: I apologize for the duplicate question. I did search for an answer, but I did not know this issue was due to the 'focus' of the button. As I result I was not finding the appropriate answers.
This happens because your Button gains focus. It is possible to remove it but that means giving the focus to something else when your button's focus Enter event is triggered.
private void button1_Enter(object sender, EventArgs e)
{
// give focus to something else
}
The problem with that is that you lose the ability to use the keyboard in order to select the button (using tab).
Moreover, a more correct approach would be to give focus to the last control that had focus instead of passing it fixed one.
have you tried to remove the focus from the button.
just call Focus(); when the button is clicked.
create custom control add ShowFocusCues and build to use
Example
public class button : System.Windows.Forms.Button
{
protected override bool ShowFocusCues
{
get
{
return false;
}
}
}
Look for button border settings.
I do not get this border, if I set the BorderSize to 0 in the FlatAppearance section
From Remove button border on tab c# winforms
You can set the ShowFocusRectangle peoperty to false.
The only answer here that really works without having to hack (moving focus to another control) is Wongsathon Tuntanakan's answer.
I refer to his answer and, as a bit of extra, I've converted his code to VB:
Public Class YourButtonClass
Inherits System.Windows.Forms.Button
Protected Overrides ReadOnly Property ShowFocusCues As Boolean
Get
Return False
End Get
End Property
End Class
Related
I have a UserControl that is dynamically added to a FlowLayoutPanel. In that same UserControl I have a button to remove itself if the user wants it, obviously at runtime. To eliminate I mean not only to eliminate that tight button, but also the full UserControl that contains the button.
The code of when the UserControl are added dynamically at the moment is as follows:
private void agregaUC() {
UserControl1 UC = new UserControl1();
aux += 1;
UC.Tag = aux.ToString();
flowLayoutPanel2.Controls.Add(UC);
}
The code to eliminate this is on the side of the form, that is, where the UserControl are being added. The button event to remove the UserControl is thrown by code through the operator + =, then there I write the suggestions that you give me.
EDIT: Based on the sample of code you've added, I've modified the below code to work better with what you are looking for. You need to find out how to access the Tag of the control you're trying to remove.
Since you don't have a reference, then you should make sure that the .Tag property can be found, because then you can do something like
foreach (Control c in flowLayoutPanel2.Controls) {
if (c.Tag == "Aux") {
flowLayoutPanel2.Controls.Remove(c);
c.Dispose();
break;
}
}
EDIT
Reading through all the comments everywhere, it seems like this is what's happening. There is a UserControl, inside that user control is a Button (Delete) and the button's Click event is subscribed to by the window, and it's in this event handler that we're trying to remove the UserControl from flowLayoutPanel2
Based on these assumptions, your function should look like this:
void UserControl_Delete_Click(object sender, EventArgs e)
{
Button Delete = (Button)sender;
UserControl UC = (UserControl)Delete.Parent;
flowLayoutControl2.Controls.Remove(UC);
UC.Dispose();
}
This is assuming a lot about the internal structure of everything, as I don't have the code to confirm this will work. It will get you a long ways down the path, though, and should only need a little tweaking based on the actual structure of the UserControl.
You can try something like that.
this.Parent.Controls.Remove(this);
Control.Parent Property.
Remark: Setting the Parent property value to null removes the control from the Control.ControlCollection of its current parent control.
So
this.Parent = null;
Edit
The code is intended to be called from within the user control itself.
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;
I've added a toggle button to my ribbon and now, I'd like to send its state to an other object. The code is below.
public void Butt_Click(Office.IRibbonControl control)
{
something.SendButtVal(control.State);
}
Of course, control.State doesn't work. I suspect that I'll need to cast control to type ToggleButton or something like that but intellisense gives me nothing...
I can see that the API for the interface IRibbonControl is here but I'd like to see a list of implementing classes, like in JavaDocs. How do I get there?
EDIT
Please note that I'm asking about a ribbon component. See the method signature. It's a toggle button on a ribbon. The problem is that I don't get Checked property and (probably) need to cast control to correct type.
You need to alter your signature. It's not correct for a toggle button. See here for details.
public void ToggleButtonOnAction(IRibbonControl control, bool pressed)
{
MessageBox.Show("ToggleButton was switched " + pressed ? "on" : "off");
}
I'm having a bit of trouble with creating one of my custom controls.
What I've got is a listbox within a usercontrol, and I need to be able to click on the lists items while still in the designer. This would make it act much like the tabcontrol.
I haven't dealt much with usercontrols but I've tried catching some overide events without success.
protected override void OnClick(EventArgs e)
{
if (DesignMode)
{
InvokeOnClick(listBox1, e);
}
base.OnClick(e);
}
I haven't been able to find anything on the web.. Any ideas on how I can do this?
Thanks in advance =)
#Bradley: thanks for pointing me in the right direction
You will need to write a ControlDesigner class, then use it in a [Designer( ... )] attribute on your UserControl.
See the example here:
http://msdn.microsoft.com/en-us/library/sycctd1z(v=VS.90).aspx
For the actual click:
http://msdn.microsoft.com/en-us/library/system.windows.forms.design.controldesigner.gethittest(v=VS.90).aspx
The ControlDesigner has a protected bool GetHitTest(Point point) method - you can implement this in your ControlDesigner and return true when you want your control to handle a click, based on the click's location on the screen.
I found this link that says you need to implement a custom designer to get the desired behavior, and explains how to make it happen.
http://social.msdn.microsoft.com/Forums/pl-PL/winforms/thread/0b6ed0cb-907c-4733-b245-ae5d0b0e6606
You may be able to get away with catching the MouseDown event in the custom control and forwarding it on to the inner control. I'm not sure how MouseDown behaves in design mode though.
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.