C# Hotkey Box (AHK Hotkey Style) - c#

I am trying within C# to create a similar Hotkey function as in AHK. Just like in any video game, you click in a box, press your hotkey and get it registered.
That's what I am trying to do with the textBox:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Keybinder
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
KeyPreview = true;
textBox1.ReadOnly = true;
textBox1.Focus();
}
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "HELLO";
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
char key = e.KeyChar;
string keystring = Char.ToString(key);
textBox1.Text = keystring;
}
}
}
However, the problem is, that I need to turn off the basic functions of the textBox, but I don't know how. For example: the cursor is still active and I can highlight the text in it.

You can set the property of the text box, Enabled to false, and then put the background color white and the font black, so it doesn´t seems like it was disabled, but you can not focus nor click on ir.
textBox1.Enabled = false;
By the way, I have a really simple library, that may be usefull.
https://github.com/PabloHorno/HotKeyDialog
Once you have the library referenced you can use it like this
or in a more simple way
var hotKey = new HotKey();
hotKey = HotKeyMessageBox.Show("Title", "A little description");
hotKey.ToString();
Or you can check if the user closes the box
HotKey hotkey = new HotKey();
if (HotKeyMessageBox.Show("Title", "Please press the key combination", out hotkey) == DialogResult.OK)
label.Text = "You have pressed the keys: " + hotkey.ToString();
else
label.Text = "You have closed the dialog. There is no input";
Hope it helps!

Why are you using a TextBox, if you do not need its functionality?
Instead of turning off it's functions, you can create a simple custom control and put it on your form. Something like:
public class KeyInput : UserControl
{
public string KeyString { get; set; } = "HELLO";
public KeyInput() : base()
{
BorderStyle = BorderStyle.Fixed3D;
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
KeyString = e.KeyChar.ToString();
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawString(KeyString, Font, SystemBrushes.ControlText, 0, 0);
}
}

Related

flickering scroll bar on side of panel whenever I use a vscrollbar I made

I have a panel with picture boxes in it and I made a seperate vscrollbar since I dont really like the one that the panel generates when you enable autoscroll, so ive got the scroll bar on the right to work but whenever I use it a scrollbar on the side of the panel starts flickering it only becomes visible when I use the scroll bar I made but it flickers like crazy until I stop moving the vscrollbar, this is the form:
and this is what ive got in the code of the scroll bar and the panel
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MetroFramework.Forms;
using MetroFramework;
namespace WindowsForm1
{
public partial class Form2 : MetroForm
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
panel1.VerticalScroll.Visible = false;
vScrollBar1.Refresh();
panel1.Refresh();
panel1.Select();
panel1.VerticalScroll.Value = 0;
panel1.AutoScroll = false;
panel1.VerticalScroll.Enabled = false;
}
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
VerticalScroll.Enabled = false;
VerticalScroll.Visible = false;
AutoScroll = false;
}
}
}
nothing I do seems to fix the problem
The AutoScroll property should be set to true in order to enable the Panel to have a virtual size. The virtual size is the size of the control itself plus the size required to accommodate the child controls. Its automatically calculated and its the size of the DisplayRectangle property. The internal VScroll and HScroll controls are updated accordingly whenever that size changes.
As a workaround to this problem, you could use an outer Panel to hide the vertical scroll bar of the inner Panel, and use the custom VScrollBar to set the scroll position. This article is an example.
In the designer, drop a new Panel to host the main one and edit the code as follows.
public partial class Form2 : MetroForm
{
public Form2()
{
InitializeComponent();
pnlOuter.AutoScroll = false; // The new Panel.
pnlInner.AutoScroll = true; // The PictureBox controls Panel.
pnlInner.AutoScrollMargin = new Size(0, 20);
pnlInner.MouseWheel += (s, e) =>
vScrollBar1.Value = pnlInner.VerticalScroll.Value;
pnlOuter.Resize += (s, e) => ResetVScrollBar();
vScrollBar1.Scroll += (s, e) =>
{
pnlInner.AutoScrollPosition = new Point(0, vScrollBar1.Value);
pnlInner.VerticalScroll.Value = vScrollBar1.Value;
};
}
private void Form2_Load(object sender, EventArgs e)
{
ResetVScrollBar();
}
private void ResetVScrollBar()
{
if (pnlInner.Width == 0 || pnlInner.Height == 0) return;
pnlInner.SetBounds(0, 0,
pnlOuter.Width + SystemInformation.VerticalScrollBarWidth * 2,
pnlOuter.Height);
vScrollBar1.Minimum = pnlInner.VerticalScroll.Minimum;
vScrollBar1.Maximum = pnlInner.DisplayRectangle.Height;
vScrollBar1.LargeChange = vScrollBar1.Maximum / vScrollBar1.Height + pnlInner.Height;
vScrollBar1.SmallChange = 15;
vScrollBar1.Value = Math.Abs(pnlInner.AutoScrollPosition.Y);
vScrollBar1.Enabled = pnlInner.Height < vScrollBar1.Maximum;
}
}

ComboBox menu repeat bug after typing in textbox in Winform app

I have a primitive app with 2 comboBoxes. They work fine after first starting the app.
However after typing in text in the search bar and pressing enter, the comboboxes loop their contents.
It happens after I type in the textbox, even if I do not press enter. Every time I press a key another repeat list of options appends to the comboBox.
How do I prevent this comboBox malfunction? Here is my code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//Nick Knapp
//CSCI 363 Fall 2019
namespace c363_hw3_2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "Library Literature Search";
this.BackColor = Color.White;
comboBox2.Items.Add("All");
comboBox2.Items.Add("Books");
comboBox2.Items.Add("Papers");
comboBox2.Items.Add("Films");
comboBox2.Items.Add("CDs");
comboBox2.Items.Add("Other");
comboBox2.SelectedIndex = 0;
comboBox1.Items.Add("Title");
comboBox1.Items.Add("Author");
comboBox1.Items.Add("Publisher");
comboBox1.Items.Add("ISBN");
comboBox1.SelectedIndex = 0;
// this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(CheckEnter);
//this.Controls.Add(textBox1);
this.ActiveControl = textBox1;
textBox1.KeyPress += new KeyPressEventHandler(keypressed);
}
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
{
textBox1.Text = "";
e.Handled = true;
}
}
private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
{
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
I think your code is correct but have you ever tried these 2 method after calling combo boxes?
comboBox1.ResetText();
comboBox1.Items.Clear();```
i think it works
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
{
textBox1.Text = "";
comboBox1.Items.Clear();
e.Handled = true;
}
}

C# Changing txtBox BackColor by Length

I want to write a simple "registration/login" program, just for me, just for fun.
I want to change the color of the TxtBox where a user types their name. When txtBox.Length<4 it should change its background to red.
I don't know why my code below isn't working. When I solidly change a text in txtBox properties to more than 5, it's blue at the start but doesn't change afterwards.
My code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _4Fun
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
if (regTxtBoxName.TextLength<4) {
regTxtBoxName.BackColor = Color.Red;
}
else{
regTxtBoxName.BackColor = Color.DarkBlue;
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void regBtn_Click(object sender, EventArgs e)
{
if (regTxtBoxName.TextLength < 4)
{
txtBoxStatus.Text = "Choose a name with minimal length 5. "; // Urobit txtboxname a pass v registru červene pozadie ak x<4
}
else {
txtBoxStatus.Text = "Your account has been successfully created.";
string name = regTxtBoxName.Text;
}
if (regTxtBoxPass.TextLength < 4)
{
txtBoxStatus.Text = txtBoxStatus.Text + "Choose password with minimal length 5. ";
}
else {
txtBoxStatus.Text = "Your account has been successfully created.";
string pass = regTxtBoxPass.Text;
}
}
}
}
Your code is setting the color in the constructor of the form and then you don't change it. You need to register to TextChanged event on your TextBox to change the colour while your application is running based on how many characters there are in your Textbox.
Handle your text box TextChanged event, and place this code there, not in constructor:
if (regTxtBoxName.TextLength<4) {
regTxtBoxName.BackColor = Color.Red;
}
else{
regTxtBoxName.BackColor = Color.DarkBlue;
}
You can do this in Textbox TextChanged event.
Here is code
void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.TextLength<4)
{
textBox1.BackColor = Color.Red;
}
else
{
textBox1.BackColor = Color.DarkBlue;
}
}
When you enter a text in text box TextChanged event will call. check this link http://www.dotnetperls.com/textchanged
You may want to change the regBtn_Click method to regBtnTextChanged. By doing so, then the color of the textBox will change on run time.
So the code would be:
private void regBtnTextChanged(object sender, EventArgs e)
{
if (regTxtBoxName.TextLength<4) {
regTxtBoxName.BackColor = Color.Red;
}
else{
regTxtBoxName.BackColor = Color.DarkBlue;
}
}

Zedgraph Control accessible from any function

I have this function:
public void MainFormLoad(object sender, EventArgs e)
{
GraphPane myPane = GRAPH.GraphPane;
}
Where myPane is a reference to GraphPane (GRAPH is name of ZedGraphControl which is displayed in GUI)
And now I want to change things like name of "x" or "y" axis, title, colors etd. or whatever you can change, but based on events. For example: I have textbox where I can write text and this text will be displayed in graph as title after textbox_textchanged_event trigger like this:
void TitleTextChanged(object sender, EventArgs e)
{
myPane.Title.Text = textbox1.Text;
}
There will be more functions like this to change properties of the graph. But this is not working.
Is there a way to come around this?
I have also tried this:
void TitleTextChanged(object sender, EventArgs e)
{
GRAPH.GraphPane.Title.Text = textbox1.text.Text;
}
but no help at all.
Please help, any advices are welcome.
**ANSWER:
So far, i have found this solution:
public void MainFormLoad(object sender, EventArgs e)
{
EditGraph(GRAPH);
}
This is the event that handles text change in text box:
public void TB_GRAPH_TITLE_VALUETextChanged(object sender, EventArgs e)
{
//GraphPane myPane2 = GRAPH.GraphPane;
changedGraphTitle = true;
EditGraph(GRAPH);
}
This is the function that find what is changed and update it:
public void EditGraph(ZedGraphControl zgc)
{
GraphPane myPane = zgc.GraphPane;
if(changedGraphTitle)
{
myPane.Title.Text = TB_GRAPH_TITLE_VALUE.Text;
changedGraphTitle = false;
zgc.Refresh();
}
}
"bool changedGraphTitle = false" must be declared also.**
If I've understood your question correctly, here's my simple code to update Zedgraph Axis Titles by a single ButtonClick event.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
namespace updateZedGraph
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
myPane = zedGraphControl1.GraphPane;
}
GraphPane myPane;
private void btn_UpdateChart_Click(object sender, EventArgs e)
{
// Update x Axis Text
myPane.XAxis.Title.Text = textBox1.Text;
// Update x Axis Text
myPane.YAxis.Title.Text = textBox2.Text;
// Refresh Chart
zedGraphControl1.Invalidate();
}
}
}
hope that helps..

C#: Drag drop controls on surface

Is there a way that one can make a control, such as a textbox, drag-droppable in C#?
I want the user to have the ability to click and hold the control with the mouse and drag it around on its surface and drop it anywhere within that surface.
Anyone has any idea how to implement this?
This answer helped me a lot. It's working great on any type of Control and Container.
If your control is moving within one container (e.g. panel), you can override OnMouseDown / OnMouseMove events, and adjust the Location property of the control.
Based on your question, it does not seem that you need full drag-and-drop (moving data between different controls or even applications).
if you're trying to drag an item from outside the silverlight container, then your best bet is to check out silverlight 4 beta
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
// wire up the various Drop events
InstallButton.Drop += new DragEventHandler(InstallButton_Drop);
InstallButton.DragOver += new DragEventHandler(InstallButton_DragOver);
InstallButton.DragEnter += new DragEventHandler(InstallButton_DragEnter);
InstallButton.DragLeave += new DragEventHandler(InstallButton_DragLeave);
}
void InstallButton_Drop(object sender, DragEventArgs e)
{
IDataObject foo = e.Data; // do something with data
}
This used to be so easy in VB6. But now we really only have what used to be called OleDrag.
Anyway, the following code should show you how. You just need a single label (dragDropLabel), and set the AllowDrop property of the form (DragDropTestForm) to True.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DragDropTest
{
public partial class DragDropTestForm : Form
{
// Negative offset to drop location, to adjust for position where a drag starts
// on a label.
private Point _labelOffset;
// Save the full type name for a label, since this is used to test for the control type.
private string labelTypeName = typeof(Label).FullName;
public DragDropTestForm()
{
InitializeComponent();
}
private void dragDropLabel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_labelOffset = new Point(-e.X, -e.Y);
}
}
private void dragDropLabel_MouseMove(object sender, MouseEventArgs e)
{
const double minimumDragDistance = 4;
const double minimumDragDistanceSquared = minimumDragDistance * minimumDragDistance;
if (e.Button == MouseButtons.Left)
{
// Minimum n pixel movement before drag starts.
if (((Math.Pow(_labelOffset.X - e.X, 2)) + Math.Pow(_labelOffset.Y - e.Y, 2)) >= minimumDragDistanceSquared)
{
dragDropLabel.DoDragDrop(dragDropLabel, DragDropEffects.Move);
}
}
}
private void DragDropTestForm_DragOver(object sender, DragEventArgs e)
{
IDataObject data = e.Data;
string[] formats = data.GetFormats();
if (formats[0] == labelTypeName)
{
e.Effect = DragDropEffects.Move;
}
}
private void DragDropTestForm_DragDrop(object sender, DragEventArgs e)
{
IDataObject data = e.Data;
string[] formats = data.GetFormats();
if (formats[0] == labelTypeName)
{
Label label = (Label) data.GetData(formats[0]);
if (label == dragDropLabel)
{
Point newLocation = new Point(e.X, e.Y);
newLocation.Offset(_labelOffset);
dragDropLabel.Location = this.PointToClient(newLocation);
}
}
}
}
}

Categories