C# Event not firing - c#

I'm trying to create a custom scrollable panel as TableLayoutPanels scroll function is not very customisable.
I have a custom class that inherits from Microsoft.Visualbasics.Powerpacks.RectangleShape. This class is used to create the scroll bar object. It contains a MouseDrag Event that is supposed to be triggered when the mouse is pressed down on the scroll bar and will terminate when the mouse comes back up.
This ScrollBar object is instantiated in another custom class that inherits from Forms.Panel.
In the main form method the custom panel is instantiated and the MouseDrag event is added to the ScrollBar. When I click the ScrollBar nothing happens. I even tested with the built in Click event and again nothing happens. Any help would be much appreciated.
Scroll Bar Class:
class ScrollBar : RectangleShape
{
public event MouseEventHandler MouseDrag;
private bool mouseHeld = false;
public bool MouseHeld { get => mouseHeld; set => mouseHeld = value; }
public ScrollBar()
{
InitializeObject();
}
public ScrollBar(int x, int y, int width, int height) : base(x, y, width, height)
{
InitializeObject();
}
private void InitializeObject()
{
this.MouseDown += new MouseEventHandler(mouseClickEvent);
}
public void mouseClickEvent(object sender, MouseEventArgs e)
{
MouseHeld = true;
MouseDrag(this, null);
}
}
Custom Panel Class:
class CustomPanel : Panel
{
private ScrollBar verticalScrollBar;
public ScrollBar VerticalScrollBar { get => verticalScrollBar; set => verticalScrollBar = value; }
public CustomPanel()
{
PanelSetup();
}
public CustomPanel(Size _size)
{
this.Size = _size;
PanelSetup();
}
private void PanelSetup()
{
//Panel setup
this.BackColor = Color.White;
this.Location = new Point(125, 125);
this.BorderStyle = BorderStyle.FixedSingle;
//Behind scrollbar graphic
RectangleShape behindScrollGraphic = new RectangleShape();
behindScrollGraphic.Width = 21;
behindScrollGraphic.Height = this.Height;
behindScrollGraphic.Location = new Point(this.Width - behindScrollGraphic.Width, 0);
behindScrollGraphic.FillStyle = FillStyle.Solid;
behindScrollGraphic.FillColor = SystemColors.Control;
behindScrollGraphic.BorderColor = Color.Transparent;
//adding behind scroll bar to panel
ShapeContainer shapeContainer = new ShapeContainer();
shapeContainer.Shapes.Add(behindScrollGraphic);
this.Controls.Add(shapeContainer);
}
public virtual void AddVerticalScrollBar()
{
ShapeContainer rectangleShapeContainer = new ShapeContainer();
rectangleShapeContainer.Shapes.Add(VerticalScrollBar);
this.Controls.Add(rectangleShapeContainer);
}
public virtual void CreateScrollBar(int _barWidth, int _barHeight)
{
int barWidth = _barWidth;
int barHeight = _barHeight;
VerticalScrollBar = new ScrollBar(this.Width - barWidth - 7, 5, 12, 30);
VerticalScrollBar.FillStyle = FillStyle.Solid;
VerticalScrollBar.FillColor = SystemColors.ControlDark;
VerticalScrollBar.BorderColor = Color.Transparent;
}
}
Main Form Class:
public partial class Form1 : Form
{
private CustomPanel panel;
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
//Form setup
this.Size = new Size(500, 500);
this.BackColor = Color.White;
//Panel setup
panel = new CustomPanel(new Size(250, 250));
panel.CreateScrollBar(10, panel.Height - 2);
panel.AddVerticalScrollBar();
//Scroll Bar
panel.VerticalScrollBar.MouseDrag += new MouseEventHandler(mouseHeldMethod);
//Add panel to form
this.Controls.Add(panel);
}
private void mouseHeldMethod(object sender, MouseEventArgs e)
{
Console.WriteLine("test");
while (panel.VerticalScrollBar.MouseHeld)
{
Console.WriteLine("Held");
}
}
}

Figured the problem out before anyone wastes their time, the control was being obstructed by another control even though visibly the other control was behind it, nothing wrong with the event call.

Related

drag up and drag down item in many item in listbox in winforms c#

i have created listbox. i inserted many items so listbox have scroll bar and also i put drag over event for drag up and drag down item. now my problem is that if i have multiple item and listbox display in scroll view than how to scroll up and scroll down my item in large set of item in listbox. please provide me solution.
thanks in advance...
To Do that you need to override OnDrawItem ex : https://www.codeproject.com/Articles/2091/ListBox-with-Icons
// GListBoxItem class
public class GListBoxItem
{
private string _myText;
private int _myImageIndex;
// properties
public string Text
{
get {return _myText;}
set {_myText = value;}
}
public int ImageIndex
{
get {return _myImageIndex;}
set {_myImageIndex = value;}
}
//constructor
public GListBoxItem(string text, int index)
{
_myText = text;
_myImageIndex = index;
}
public GListBoxItem(string text): this(text,-1){}
public GListBoxItem(): this(""){}
public override string ToString()
{
return _myText;
}
}//End of GListBoxItem class
// GListBox class
public class GListBox : ListBox
{
private ImageList _myImageList;
public ImageList ImageList
{
get {return _myImageList;}
set {_myImageList = value;}
}
public GListBox()
{
// Set owner draw mode
this.DrawMode = DrawMode.OwnerDrawFixed;
}
protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
GListBoxItem item;
Rectangle bounds = e.Bounds;
Size imageSize = _myImageList.ImageSize;
try
{
item = (GListBoxItem) Items[e.Index];
if (item.ImageIndex != -1)
{
imageList.Draw(e.Graphics, bounds.Left,bounds.Top,item.ImageIndex);
e.Graphics.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor),
bounds.Left+imageSize.Width, bounds.Top);
}
else
{
e.Graphics.DrawString(item.Text, e.Font,new SolidBrush(e.ForeColor),
bounds.Left, bounds.Top);
}
}
catch
{
if (e.Index != -1)
{
e.Graphics.DrawString(Items[e.Index].ToString(),e.Font,
new SolidBrush(e.ForeColor) ,bounds.Left, bounds.Top);
}
else
{
e.Graphics.DrawString(Text,e.Font,new SolidBrush(e.ForeColor),
bounds.Left, bounds.Top);
}
}
base.OnDrawItem(e);
}
}//End of GListBox class
Or you can use different controls as DataGridView or ListView
ex:How do add image to System.Windows.Forms.ListBox?
I think that FlowLayoutPanel (or TableLayoutPanel ) can be suitable for that need,
here is a basic example, comments inside the code:
private void Form1_Load(object sender, EventArgs e)
{
// declare flowlayout panel
FlowLayoutPanel fl = new FlowLayoutPanel();
fl.Size = new Size(500, 800);
// this will add a scroll bar when the children height are greater than the height
fl.AutoScroll = true;
this.Controls.Add(fl);
// add pictureboxes that shows the bitmaps
for (int i = 0; i < 20; i++)
{
Bitmap b = new Bitmap(#"C:\Users\xxx\xxx\xxx.png");
PictureBox p = new PictureBox();
p.Image = b;
p.Size = new Size(fl.Width, 50);
fl.Controls.Add(p);
}
}

Mouse events for Picture box that is Created in a C# class

I am Creating a Chess.I added a Picture box on design form as Chessboard..then for each piece (for example horse or elephant and...) Added a Class.cs and created picture box for each piece in those classes.like this:
public class Mohre
{
public Mohre()
{
}
public void draw(Form form,PictureBox pic )
{
pic.Size = new System.Drawing.Size(50, 50);
pic.Image = Chess1.Properties.Resources.sarbaz;
pic.SizeMode = PictureBoxSizeMode.StretchImage;
pic.Visible = true;
form.Controls.Add(pic);
pic.BringToFront();
}
}
&
public class Soldier:Mohre
{
public PictureBox picsoldier = new PictureBox();
public Soldier()
{
picsoldier.Left = 436;
picsoldier.Top = 670;
}
public void movement()
{
picsoldier.Top -= 67;
}
}
(not add picture box on design form Directly.) now I want to when user click on the pieces that created in classesÙˆ movement function will be called.
what should I Do?
You mean this ?
lblname.Click += delegate { nameOfUrFunction (lblname); };
private void nameOfUrFunction (Label lbl)
{
}

Xamarin Derived UIControl TouchUpInside event isn't working

I'm trying to set an TouchUpInside event to my class that inherit from UIControl.
First, I've tried to set the event to each control separately, in the same class, and it's also not working.
Than, I've tried to set the event from the window that present this UIControl, but also isn't working.
The class drawing two controls, Button and TextField:
public class SingleItemView : UIControl
{
public UIButton RadioButton { get; set; }
public override void Draw(RectangleF rect)
{
base.Draw(rect);
this.UserInteractionEnabled = true;
RadioButton = new UIButton(rect);
RadioButton.SetImage(UIImage.FromFile("images/Unknown_Gray.png"), UIControlState.Normal);
RadioButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Left;
this.AddSubview(RadioButton);
var textField = new UITextField(new RectangleF(rect.X + 25, rect.Y, rect.Width, rect.Height));
textField.Placeholder = "Place Holder is here";
this.AddSubview(textField);
}
}
The ViewController that signs the event:
public class ItmesView : UIViewController
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
var item = new SingleItemView();
item.Draw(new RectangleF(10, 60, 50, 30));
item.TouchUpInside += item_TouchUpInside;
this.View.AddSubview(item);
}
}
None of the events I've tried isn't working, any suggestion?
Thanks.

Show ToolTip with ComboBox (dropdownmenu)

I am showing a little tooltip, but if I change the selecteditem/text in the dropdownmenu, tooltip shows the old text and the new text. I want it to show only the new text.
private void optionsvalueComboBox_MouseHover(object sender, EventArgs e)
{
ToolTip buttonToolTip = new ToolTip();
buttonToolTip.ToolTipTitle = "Value";
buttonToolTip.UseFading = true;
buttonToolTip.UseAnimation = true;
buttonToolTip.IsBalloon = true;
buttonToolTip.ShowAlways = true;
buttonToolTip.AutoPopDelay = 5000;
buttonToolTip.InitialDelay = 1000;
buttonToolTip.ReshowDelay = 0;
buttonToolTip.SetToolTip(optionsvalueComboBox, optionsvalueComboBox.Text);
}
Assuming what you don't like is the tooltip text changing from the old text to the new text...
The reason it's doing that is because you are creating a new tooltip instance on every hover event. Every time the hover event is fired, the old tooltip instance is replaced with a new one which is why you see both. To fix this, put the declaration outside the event, like this:
ToolTip buttonToolTip = new ToolTip();
private void optionsvalueComboBox_MouseHover(object sender, EventArgs e)
{
buttonToolTip.ToolTipTitle = "Value";
buttonToolTip.UseFading = true;
buttonToolTip.UseAnimation = true;
buttonToolTip.IsBalloon = true;
buttonToolTip.ShowAlways = true;
buttonToolTip.AutoPopDelay = 5000;
buttonToolTip.InitialDelay = 1000;
buttonToolTip.ReshowDelay = 0;
buttonToolTip.SetToolTip(optionsvalueComboBox, optionsvalueComboBox.Text);
}
Now the same tooltip is being used with the wording simply being replaced. Let me know if this works for you!
I've tried digging in the MouseHover event of a ComboBox and looks like it doesn't work normally as we expect. The MouseHover is in fact fired only when you move the mouse over the drop down button if your ComboBox has style of dropdown. The simplest solution for this is change your combobox style to dropdownlist like this:
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
However that kind of style will make the ComboBox readonly. If that's not what you want, there is a work-around for you is to use the event MouseMove with a Timer to mimic the MouseHover, here is the code for you:
public partial class Form1 : Form {
public Form1(){
InitializeComponent();
t.Interval = 600;
t.Tick += (se, ev) => {
buttonToolTip.SetToolTip(comboBox1, (string)comboBox1.SelectedItem);
t.Stop();
};
//init the buttonToolTip
buttonToolTip.ToolTipTitle = "Value";
buttonToolTip.UseFading = true;
buttonToolTip.UseAnimation = true;
buttonToolTip.IsBalloon = true;
buttonToolTip.ShowAlways = true;
buttonToolTip.AutoPopDelay = 5000;
buttonToolTip.InitialDelay = 1000;
buttonToolTip.ReshowDelay = 0;
//register MouseMove event handler for your comboBox1
comboBox1.MouseMove += (se, ev) => {
//Restart the timer every time the mouse is moving
t.Stop();
t.Start();
};
}
Timer t = new Timer();
ToolTip buttonToolTip = new ToolTip();
}
A complete working example:
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public RECT(Rectangle rect)
{
Left = rect.Left;
Top = rect.Top;
Right = rect.Right;
Bottom = rect.Bottom;
}
public Rectangle Rect
{
get
{
return new Rectangle(Left, Top, Right - Left, Bottom - Top);
}
}
public Point Location
{
get
{
return new Point(Left, Top);
}
}
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public class ToolTipComboBox: ComboBox
{
#region Fields
private ToolTip toolTip;
private bool _tooltipVisible;
private bool _dropDownOpen;
#endregion
#region Types
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
public struct COMBOBOXINFO
{
public Int32 cbSize;
public RECT rcItem;
public RECT rcButton;
public ComboBoxButtonState buttonState;
public IntPtr hwndCombo;
public IntPtr hwndEdit;
public IntPtr hwndList;
}
public enum ComboBoxButtonState
{
// ReSharper disable once UnusedMember.Global
StateSystemNone = 0,
// ReSharper disable once UnusedMember.Global
StateSystemInvisible = 0x00008000,
// ReSharper disable once UnusedMember.Global
StateSystemPressed = 0x00000008
}
[DllImport("user32.dll")]
public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
#endregion
#region Properties
private IntPtr HwndCombo
{
get
{
COMBOBOXINFO pcbi = new COMBOBOXINFO();
pcbi.cbSize = Marshal.SizeOf(pcbi);
GetComboBoxInfo(Handle, ref pcbi);
return pcbi.hwndCombo;
}
}
private IntPtr HwndDropDown
{
get
{
COMBOBOXINFO pcbi = new COMBOBOXINFO();
pcbi.cbSize = Marshal.SizeOf(pcbi);
GetComboBoxInfo(Handle, ref pcbi);
return pcbi.hwndList;
}
}
[Browsable(false)]
public new DrawMode DrawMode
{
get { return base.DrawMode; }
set { base.DrawMode = value; }
}
#endregion
#region ctor
public ToolTipComboBox()
{
toolTip = new ToolTip
{
UseAnimation = false,
UseFading = false
};
base.DrawMode = DrawMode.OwnerDrawFixed;
DrawItem += OnDrawItem;
DropDownClosed += OnDropDownClosed;
DropDown += OnDropDown;
MouseLeave += OnMouseLeave;
}
#endregion
#region Methods
private void OnDropDown(object sender, EventArgs e)
{
_dropDownOpen = true;
}
private void OnMouseLeave(object sender, EventArgs e)
{
ResetToolTip();
}
private void ShowToolTip(string text, int x, int y)
{
toolTip.Show(text, this, x, y);
_tooltipVisible = true;
}
private void OnDrawItem(object sender, DrawItemEventArgs e)
{
ComboBox cbo = sender as ComboBox;
if (e.Index == -1) return;
// ReSharper disable once PossibleNullReferenceException
string text = cbo.GetItemText(cbo.Items[e.Index]);
e.DrawBackground();
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds.Location, SystemColors.Window);
if (_dropDownOpen)
{
Size szText = TextRenderer.MeasureText(text, cbo.Font);
if (szText.Width > cbo.Width - SystemInformation.VerticalScrollBarWidth && !_tooltipVisible)
{
RECT rcDropDown;
GetWindowRect(HwndDropDown, out rcDropDown);
RECT rcCombo;
GetWindowRect(HwndCombo, out rcCombo);
if (rcCombo.Top > rcDropDown.Top)
{
ShowToolTip(text, e.Bounds.X, e.Bounds.Y - rcDropDown.Rect.Height - cbo.ItemHeight - 5);
}
else
{
ShowToolTip(text, e.Bounds.X, e.Bounds.Y + cbo.ItemHeight - cbo.ItemHeight);
}
}
}
}
else
{
ResetToolTip();
TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds.Location, cbo.ForeColor);
}
e.DrawFocusRectangle();
}
private void OnDropDownClosed(object sender, EventArgs e)
{
_dropDownOpen = false;
ResetToolTip();
}
private void ResetToolTip()
{
if (_tooltipVisible)
{
// ReSharper disable once AssignNullToNotNullAttribute
toolTip.SetToolTip(this, null);
_tooltipVisible = false;
}
}
#endregion
}

C# override properties

I have a control which has Textbox and Panel. I need to transfer from the panel ForeColor in textbox. I do so but does not work.
public Color ForeColor
{
get
{
return transparentTextBox.ForeColor;
}
set
{
transparentTextBox.ForeColor = value;
}
}
Do this in steps:
Do not expose the TextBox and Panel to the outside world, make them private controls (private to the Control that contains them). Your control may expose properties such as Text (which then gets/sets the same property on the TextBox).
Expose a PanelColor property that is of type Color. When this property is set, set that color in both the Panel and the TextBox.
This way, your Control only exposes the properties that it has to (the Encapsulation principle) and you can react to property changes any way you want.
Maybe something like this:
class MyTextBox : TextBox // custom textbox
{
protected override void OnParentForeColorChanged(EventArgs e)
{
ForeColor = Parent.ForeColor;
Invalidate();
base.OnParentForeColorChanged(e);
}
}
But there is other solution.
i don't know what's that property is, but it's not an override and not an event handler so there is no way it will work. i think the best way to do what you want is just set
transparentTextBox.ForeColor = pnl.ForeColor;
in the initialize of the control.
if someone else is going to change the panel's foreColor then make a method or property that do
pnl.ForeColor = givenValue;//givenValue is the value the user gave to change the panel's foreColor
transparentTextBox.ForeColor = givenValue;
for example this userControl do that:
public partial class UserControl1 : UserControl
{
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.TextBox textBox1;
public UserControl1()
{
InitializeComponent();
this.panel1 = new System.Windows.Forms.Panel();
this.textBox1 = new System.Windows.Forms.TextBox();
this.panel1.Controls.Add(this.textBox1);
this.panel1.Location = new System.Drawing.Point(3, 14);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(200, 100);
this.panel1.TabIndex = 0;
this.textBox1.Location = new System.Drawing.Point(33, 15);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;
this.Controls.Add(this.panel1);
textBox1.ForeColor = panel1.ForeColor;
}
public Color ForeColor
{
get
{
return textBox1.ForeColor;
}
set
{
panel1.ForeColor = value;
textBox1.ForeColor = value;
}
}
}
private Color _foreColor = null;
public Color ForeColor
{
get
{
if(_forecolor == null)
{
_foreColor = transparentTextBox.ForeColor;
}
return _foreColor;
}
}
I had same problem. Instead of overriding ForeColor property do this :
public UserControl1()
{
InitializeComponent();
ForeColorChanged += UserControl1_ForeColorChanged;
}
void UserControl1_ForeColorChanged(object sender, EventArgs e)
{
textBox1.ForeColor = ForeColor;
}
Not a really beautiful approch but it works :)

Categories

Resources