I want my Win-Forms application (which has many different forms) to accept only certain characters of user input. This restriction should apply to all forms, all input fields, etc. Is there any simple solution to implement this without adding keyboard-events to every single form and even better, without changing any existing form?
First I have thought of a low-level keyboard hook but this would be applied globally to every user input in every application running on the system which isn't the ideal solution, I guess. Any other possibilities or suggestions?
You can do that if you create a custom control for each control you need and set your control to inherit the core controls. For example, this code will prevent clicking on zero:
public class MyTextBox : TextBox
{
protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.D0)
e.SuppressKeyPress = true;
}
}
You can even drag this control from the toolbox (after you build).
Related
Here is what I have tried and is working. But I want to whether this is proper or is there a better option or way to do the same
private void tabs_SelectedIndexChanged(object sender, EventArgs e)
{
TabControl control = (TabControl)sender;
if(control.SelectedIndex == 3 || control.SelectedIndex == 0)
{
button1.Parent = control.SelectedTab;
zonalarealabel.Parent = control.SelectedTab;
pictureBox3.Parent = control.SelectedTab;
}
}
If you don't mind coupling your code to your user interface then your approach is valid. However, I think the better option is to create a user control that raises events handled by the selected tab. The user control would appear on tabs 0 and 3 at all times. The advantage of this is that you don't need to modify your SelectedIndexChanged event handler should you want these buttons to appear on a future tab. There are many ways to approach this problem, but given the very narrow functional requirements you shared, it's a better design to relegate these buttons to a user control rather than re-parent them at runtime.
Currently I'm creating a really big project in Visual Studio 2012, where there are some common settings for each form ("Cancel" and "Save" buttons, Methods that change in every form but have the same name, font sizes and types, form color etc.) it will save me a lot of time if I could do all the design a single windows form and when I edit or modify it, have the changes reflected in the other forms as well.
Let's say I need 10 forms, to create them I would choose this default format and have my menu and basic objects already placed and designed; then after 10 forms I decided to move a button a bit, but don't want to go to every form and move it; just change it in the original format, refresh and all my forms will have that button in the new location.
I used Templates as recommended by Can one set the default properties for new WinForms created in Visual Studio?. But I still have the issue that if I change something in the template it won't refresh in every other form created with the template to that point.
I've already thought of changing the InitializeComponent in the WinForm default format, but this is not recommended and I wouldn't want any errors from this later on.
Any ideas?
Thanks in advance
Inheritance will work for your solution.
Create "base" form with all "common" controls
Create new "derived" form and change form to inherit from your "base" form.
If you have some common logic in base form, which need to be "overridden" in derived forms - put it to the virtual method
// Base form
protected virtual void Close()
{
// Base logic
}
private void CloseButton_Click(object sender, EventArgs e)
{
Close();
}
// In derived form - just override "Close" method
protected override void Close()
{
// custom logic - will be executed when "Close" button clicked
}
In base form leave empty space for custom controls. Because you will not be able access baseform controls through designer in derived form.
Another approach - Model-View-ViewModel(MVVM)
- Introduce own UserControl with common controls(view) which have property - instance of ViewModel.(Viewmodel will contains behaviour logic and possibility to change "base" settings.)
- Add this user control to all "derived" forms and set UserControl.ViewModelProperty to instance which will represent logic for this particular form.
Without knowing "full" context of your goals - difficult to suggest more, but I am pretty sure you can build maintainable relations between forms, which can share common logic and view.
No, there is nothing you can do. Once you use a template to create a project or a file, it becomes a one-off. You have to edit it manually, or use a text editor that is powerful enough to employ a find and replace with pattern matching and capture group insertion.
I have designed custom user control in c# .This user control is include :
textbox,check box,button.
Now I want to consume designed user control in my project but the problem is I can't access to the textbox,checkbox,button EVENTS when consume user control in my form and there are only EVENTS for user control.how can I make it possible that each object events become accessible when consuming designed user control ?
In your user control set your control like "text-box" Modifiers property to Public.so when you add this user control to your form. you can access to your text box evens:
public Form1()
{
InitializeComponent();
userControl11.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
}
void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("user control textbox.text changed");
}
you might need to manually create public events for the events of those controls which you want to be accessible from outside.
another way is, when initializing those controls in you user control, using public instead of private (which is automatically generated by VS), these code should be located in the xxx.Designer.cs, and they looks likeprivate System.Windows.Forms.Button button1. Then it can be accessed through MyUserControl.button1. But doing so, the entire control will be accessible from outside of your user control, which does not feel very well personally.
I think you should add public events to your custom control class, and make subscribing and unsubscribing there. Just like that:
public event EventHandler ComboboxClick
{
add { _combobox.Click += value; }
remove { _combobox.Click -= value; }
}
For more information see http://msdn.microsoft.com/en-us/library/8627sbea(v=vs.71).aspx
Edit: I would not recomend setting inner controls of your custom control as public properties, because it's a violation of encapsulation principle. You design your own control to do some specific job and clients of the control should stay unaware of its inner composition. Should you change the inner composition of your control in future (switch to some 3rd party textbox control, for example), you would only need to make changes in your custom control class, and its clients would still work properly as if nothing has happend. Here's a good koan about encapsulation =)
Other than creating a custom button, and a custom textbox, and a custom label, etc, and then using those controls across all the forms of the application, and then changing the default colors and fonts of those controls as needed, is there an easy way to implement this kind of css-like functionality on an existing application that contains several forms?
By the way, I know that I could just programatically open each *.Designer.cs file and then search/replace instances of "System.Windows.Forms.[Control]" with "My.Namespace.My[Control]", but I'm not sure how that would work in cases where the code sets the controls' fonts and colors and similar properties. Would it then just be a matter of making sure that the custom controls override all the relevant getter methods?
Windows Forms does not provide any kind of skinning.
An easy workaround could be to write some kind of extension method on the Form class:
public static void ApplySkin(this Form form, Skin skin)
{
foreach (Control ctrl in form.Controls)
{
if (ctrl is TextBox)
{
TextBox textBox = (TextBox)ctrl;
textBox.BackColor = skin.BackColor;
textBox.ForeColor = skin.ForeColor;
textBox.Font = skin.Font;
...
}
else if (ctrl is ComboBox)
{
ComboBox comboBox = (ComboBox)ctrl;
comboBox.BackColor = skin.BackColor;
comboBox.ForeColor = skin.ForeColor;
comboBox.Font = skin.Font;
...
}
else if (ctrl is ...)
}
}
About the Designer.cs files - you should probably avoid changing their code at all. They are used by the designer and are seperated for a reason.
If you do want to change stuff, in the Form CTOR, after calling InitializeComponent(), simply call your own function with whatever changes you would like (changing attribute values such as colors, delegates etc...)
If you want several forms to have the same style (or functionality), just put this method in a different class and have all the forms use the same method by sending themselves as parameters.
Now ofcourse the method won't know which controls are on which forms so you can use Controls.Find (one of Form methods) to locate controls by name. Just make sure that the controls in your form are named correctly using the same conventions (for example, all list boxes will be named listBoxX where X is the number...).
I really had no idea what to title this question.
Assume I have a windows form application. The GUI is complex enough to require two custom user controls, "LeftSide" and "Rightside" which each are composed from various buttons, labels, and maybe even another custom user control.
My question:
I am in in the scope of the "Rightside" control. How would I call a method from the "Leftside" control?
I am using Visual Studio 2008.
The simplest solution is to make a property on the RightSide control of type LeftSide, then set it to the LeftSide instance in the form designer.
You can then call public methods on the property.
However, this is poor design.
Each usercontrol should be a self-contained block that doesn't need to directly interact with other usercontrols.
You should consider restructuring your form.
Exact equivalent with standard WF controls: how to keep the text of one text box in sync with another:
private void textBox1_TextChanged(object sender, EventArgs e) {
textBox2.Text = textBox1.Text;
}
Necessary ingredients: an event on your user control that is fired when something interesting happens. And public properties.