I am creating a custom control. On that control I have around 20 sub controls. When i move the cursor on my User Control, i want the cursor to be changed according to sub control it is moving on.
Eg:
User Control
--Control 1 : if(Condition 1) { Mouse - Wait } else { Mouse - Default }
--Control 2 : if(Condition 1) { Mouse - Hand } else { Mouse - Default }
--Control 3 : Mouse - Default
......so on.
Is there any way to determine on MouseMove Event of User Control that i am moving on which sub control so that i can change my cursor in a single event.
You don't need to rely on events, can use the Cursor Property of the given control. For example, if you have three TextBoxes, you can change this property in the "properties box" on the "Design View" or just write:
textBox1.Cursor = Cursors.WaitCursor;
textBox2.Cursor = Cursors.Hand;
textBox3.Cursor = Cursors.Default;
The cursor would show the given shape when "entering" in each Textbox.
You can assign to EACH usercontrol's mouse-over or You can assign to ONE event handler, which is the same for all Your controls. Depending on which technique You choose, You then can set the cursor, the second technique requires to a ) a hardcoded if / else or switch case or b ) reflection casting sender to right type and then setting the mouse-cursor.
Did this help ?
You can do this way. Suppose you have three buttons having name as button1, button2 & button3.
Write this on form load
this.button1.MouseHover += new System.EventHandler(this.MouseHover);
this.button2.MouseHover += new System.EventHandler(this.MouseHover);
this.button3.MouseHover += new System.EventHandler(this.MouseHover);
Now write this as new event :
private void MouseHover(object sender, EventArgs e)
{
Button oButton = (Button)sender;
if (oButton.Name == "button1")
{
oButton.Cursor = Cursors.WaitCursor;
}
else if (oButton.Name == "button2")
{
oButton.Cursor = Cursors.Hand;
}
else if (oButton.Name == "button3")
{
oButton.Cursor = Cursors.Default;
}
}
It will work as you need.
Thanks
Related
I made a simple button, but when i click outside of win form my button getting a black border. By the way i set BorderSize to "0" and it works great while i clicking inside of my form.
this.button.FlatAppearance.BorderSize = 0;
That's how it looks like.
it seems a focus problem. Try to reset the focus when the cursor leave the control.
Add these lines of code to your forms load event.
btn.FlatStyle = FlatStyle.Flat;//You can also use the popup flat style
btn.FlatAppearance.BorderColor = btn.Parent.BackColor;
btn.FlatAppearance.BorderSize = 0;
One simple workaround is to set the FlatAppearance.BorderColor of the Button to its Parent.BackColor:
this.button1.FlatAppearance.BorderColor = this.button1.Parent.BackColor;
You could set this Property subscribing to the ParentChanged event (or overriding OnParentChanged, if it's a Custom Control) if the Control can be assigned to another parent at some point.
You can also perform the same operation in batch, using the HandleCreated event and have all the Buttons (with FlatStyle = FlatStyle.Flat) subscribe to the event in the Form's constructor:
public Form1()
{
InitializeComponent();
foreach (Button button in this.Controls.OfType<Button>().Where(btn => btn.FlatStyle == FlatStyle.Flat))
{
button.HandleCreated += (s, e) => {
button.FlatAppearance.BorderColor = button.Parent.BackColor;
};
}
}
Hey so I am attempting to create a form in which there are two buttons (acting as tabs) on the side in which when one is pressed specific controls are shown and when the other is pressed, another set are shown.
I have gotten this to work very well however I have run into an issue when about to create my second set of controls, how am I going to draw them (in designer) ontop of current controls (it's fine during runtime)? So my question is, how can I make this work. Current (possibly) important code:
private void CheatButton_Click(object sender, EventArgs e)
{
CheatControls(true);
ColorControls(false);
CheatButton.Normalcolor = Color.FromArgb(51, 51, 51);
ColorButton.Normalcolor = Color.FromArgb(61, 61, 61);
}
private void ColorButton_Click(object sender, EventArgs e)
{
CheatControls(false);
ColorControls(true);
CheatButton.Normalcolor = Color.FromArgb(61, 61, 61);
ColorButton.Normalcolor = Color.FromArgb(51, 51, 51);
}
private void CheatControls(bool b)
{
TriggerSwitch.Visible = b;
TriggerLabel.Visible = b;
BhopSwitch.Visible = b;
BhopLabel.Visible = b;
GlowSwitch.Visible = b;
GlowLabel.Visible = b;
RecoilSwitch.Visible = b;
RecoilLabel.Visible = b;
}
private void ColorControls(bool c)
{
}
My windows form application with an understandable graphic
Put all your cheat controls in a custom UserControl and all your color controls in a different custom UserControl. You can edit the different control sets easily in the designer, and in your code you can hide/show them more easily by setting the appropriate UserControl's visibility rather than setting the visibility of a bunch of controls individually. Here's an (admittedly old) example of creating a UserControl: msdn.microsoft.com/en-us/library/aa302342.aspx
When you create a UserControl in Visual Studio, you can add the controls to it using the designer. In your form with the tab buttons, you would add instances of the two UserControls that you created. Since UserControl derives from Control, it has a Visible property. So, in your CheatControls(bool b) method, your implementation would be simplified to something like _myCheatControls.Visible = b;. I haven't watched the whole thing, but this video might help, too: youtube.com/watch?v=l5L_q_jI494
You can use
XanderUI
Simply add a SuperButton(acts as a tab button) and when its clicked show a panel with your controls in it
EG -
private void ShowControlSet(int ControlSet)
{
panel1.visible = false;
panel2.visible = false;
if (ControlSet == 1) panel1.visible = true;
if (ControlSet == 2) panel2.visible = true;
}
// To show a panel use
ShowControlSet(1);
Your also able to use BringToFront() instead of making each panel invisible / visible but you need to anchor or dock the panels correctly
asides the visibility, what you can do is get the position of the buttons and st them when hiding and showing the other buttons
just set the top and left positions, ensuring the buttons are the same size.
Right, so I have 13 textboxes with corresponding labels that are assigned after a user decides the name from a different form (instantiated by the 'Add field...' button). The issue arises when the user wishes to delete a textbox with previously entered data, as this results in an empty space where the textbox and label originally were as visualized by the following image:
My question is: how do I make it so that when a user chooses to delete a textbox, the textbox-label pair(s) that follow it replace the deleted textbox AND shift the remaining textboxes accordingly.
Textbox-label pairs in designer:
I've thought about this problem intensively over the past few days, and have concluded that with my current knowledge of C# I am limited to solving this issue with a horrendously tedious amount of if-statements (talking hundreds - thousands here). Any and all help would be appreciated!
Current code on the X-button for first textbox-label pair:
private void xButton1_Click(object sender, EventArgs e)
{
label14.Text = "";
textBox1.Text = "";
if (label14.Text.Equals(""))
{
label14.Visible = false;
textBox1.Visible = false;
xButton.Visible = false;
label14.Text = "";
textBox1.Text = "";
}
if (!textBox2.Text.Equals(""))
{
label14.Text = label15.Text;
textBox1.Text = textBox2.Text;
}
if (!textBox2.Text.Equals("") && (textBox3.Text.Equals("")))
{
label15.Visible = false;
textBox2.Text = "";
textBox2.Visible = false;
xButton2.Visible = false;
}
}
One simple thing you could do is give all your "dynamic" controls (label, textbox, button) a similar value in their Tag property (in my example, I used the string "dynamic" for all the control Tags. This enables you to query for them easily.
Next, you could follow the logic that, anytime you delete some controls, you move all controls below the deleted ones up a distance equal to the height of the control being deleted plus whatever padding you have between the controls.
For example, when a user clicks the X button, since you know the value of the Bottom of the control that's being deleted, you could find all controls that had a matching Tag property whose Top is greater than the x button Bottom, and you can move them up.
Here's an example (this assumes that all your X buttons are mapped to this same click event):
private void buttonX_Click(object sender, EventArgs e)
{
// This is represents the distance between the bottom
// of one control to the top of the next control
// Normally it would be defined globally, and used when you
// lay out your controls.
const int controlPadding = 6;
var xButton = sender as Button;
if (xButton == null) return;
var minTopValue = xButton.Bottom;
var distanceToMoveUp = xButton.Height + controlPadding;
// Find all controls that have the Tag and are at the same height as the button
var controlsToDelete = Controls.Cast<Control>().Where(control =>
control.Tag != null &&
control.Tag.ToString() == "dynamic" &&
control.Top == xButton.Top)
.ToList();
// Delete the controls
controlsToDelete.ForEach(Controls.Remove);
// Get all controls with the same tag that are below the deleted controls
var controlsToMove = Controls.Cast<Control>().Where(control =>
control.Tag != null &&
control.Tag.ToString() == "dynamic" &&
control.Top > minTopValue);
// Move each control up the specified amount
foreach (var controlToMove in controlsToMove)
{
controlToMove.Top -= distanceToMoveUp;
}
}
I have a tab control in my WPF application with multiple tabs. Each tab gives access to several buttons, text boxes, drop downs. Now before moving to the next tab valid entries in each of the controls in the tab is to be checked or jumping to the next tab should not be allowed. How can this be done?
I was able to use IsEnable property to do this. But I want it like, when I click on the next tab it should, without entering the next tab, display a warning that such and such entry in the present tab is not valid.
If you adhere to the Selected event you can do something like this:
// Keep a global variable for the previous index
int prevIndex = 0;
private void tabControl_Selected(object sender, TabControlEventArgs e)
{
TabControl tc = sender as TabControl;
if (tc != null)
{
bool letSwitchHappen = validateTabControls(tc.SelectedIndex);
if (!letSwitchHappen)
{
tc.SelectedIndex = prevIndex;
}
prevIndex = tc.SelectedIndex;
}
}
Where validateTabControls is something like:
private bool validateTabControls(int tabIndex)
{
bool validEntries = false;
// Some code here to set validEntries according to the control at tabIndex
return validEntries;
}
Take a look at this example from Josh Smith.
It shows explicitly how to do this, and Josh is well-known (and respected) in the WPF world.
Are there any controls that can dynamically create a group of radio buttons from a list of objects? Something similar to the CheckedBoxList control, but with mutually exclusive selection. This question points out this control doesn't exist natively for WinForms but are there any third party controls that do this?
Control vendors can't make any money with controls like that. Here's some code to get your started:
using System;
using System.Drawing;
using System.Windows.Forms;
class RadioList : ListBox {
public event EventHandler SelectedOptionChanged;
public RadioList() {
this.DrawMode = DrawMode.OwnerDrawFixed;
this.ItemHeight += 2;
}
public int SelectedOption {
// Current item with the selected radio button
get { return mSelectedOption; }
set {
if (value != mSelectedOption) {
Invalidate(GetItemRectangle(mSelectedOption));
mSelectedOption = value;
OnSelectedOptionChanged(EventArgs.Empty);
Invalidate(GetItemRectangle(value));
}
}
}
protected virtual void OnSelectedOptionChanged(EventArgs e) {
// Raise SelectOptionChanged event
EventHandler handler = this.SelectedOptionChanged;
if (handler != null) handler(this, e);
}
protected override void OnDrawItem(DrawItemEventArgs e) {
// Draw item with radio button
using (var br = new SolidBrush(this.BackColor))
e.Graphics.FillRectangle(br, e.Bounds);
if (e.Index < this.Items.Count) {
Rectangle rc = new Rectangle(e.Bounds.Left, e.Bounds.Top, e.Bounds.Height, e.Bounds.Height);
ControlPaint.DrawRadioButton(e.Graphics, rc,
e.Index == SelectedOption ? ButtonState.Checked : ButtonState.Normal);
rc = new Rectangle(rc.Right, e.Bounds.Top, e.Bounds.Width - rc.Right, e.Bounds.Height);
TextRenderer.DrawText(e.Graphics, this.Items[e.Index].ToString(), this.Font, rc, this.ForeColor, TextFormatFlags.Left);
}
if ((e.State & DrawItemState.Focus) != DrawItemState.None) e.DrawFocusRectangle();
}
protected override void OnMouseUp(MouseEventArgs e) {
// Detect clicks on the radio button
int index = this.IndexFromPoint(e.Location);
if (index >= 0 && e.X < this.ItemHeight) SelectedOption = index;
base.OnMouseUp(e);
}
protected override void OnKeyDown(KeyEventArgs e) {
// Turn on option with space bar
if (e.KeyData == Keys.Space && this.SelectedIndex >= 0) SelectedOption = this.SelectedIndex;
base.OnKeyDown(e);
}
private int mSelectedOption;
}
Maybe; But this is easier and better to write yourself, though (unless somebody suggests either a free control or better yet sourcecode you can drop into your project).
A little GUI wisdom (I did not make this up but am too lazy to include references):
If a list of radio buttons will ever have > 7-10 items, use a list box.
Of course I gather either you don't have control of that or if you do, won't settle for that answer.
Add a scrollable panel to your form
in code, loop thru your list of objects. Inside the loop:
Make a new radiobutton
set the .top property to the .bottom of the previous one (or 0 if no previous)
put a copy of your object in the .Tag property (so you can tell which object was selected)
set the width so you don't get a horizontal scrollbar in your scrollable control
set the .text appropriately. You may need to truncate to avoid wrapping. If you want to go multiline for lines that wrap, you have to increase the height then, but this would require a lot of gymnastics with control.creategraphics, graphics.MeasureString, and other GDI+ features. See the Bob Powell's GDI+ FAQ.
add a handler so the checkchanged can be processed (AddHandler MyRB, addressof CC_Sub)
add it to the scrollable control
Add the CC_Sub mentioned above - can get right function signature by adding a radiobutton, putting on the handler for CheckChanged, and deleting radio button
In this sub, set a form-level variable of type of your class to the tag of the sender (you'll have to do ctypeing)
When your user clicks OK, return that variable, that is the object picked.
OK so it looks hard. So is either squeezing this out of management or doling out cash.
If you want fancier stuff, you can make a usercontrol with labels, checkboxes/radio buttons, etc. in it. You have to handle selecting/unselecting. Then add the usercontrol to a scrollable panel instead of the radiobutton. This provides almost unlimited flexibility.