Design UserControl with Textbox and Label with Properties in grid - c#

Check the image of form and see the below code to get that functionality
Here is some code which i had done.
I am working on user control library project and i drag a label and textbox on it.
Please check the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CustomControls
{
public partial class CustomTextbox: UserControl
{
public enum Directions
{
Left, Right, Top, Bottom
}
[Description("Define the Text Property of label")]
public string Description {
get
{
return label1.Text;
}
set
{
label1.Text = value;
}
}
[Description("Define the location of label")]
public Point LabelLocation
{
get
{
return label1.Location;
}
set
{
label1.Location = value;
}
}
[Description("Define the location of Textbox")]
public Point TextboxLocation
{
get
{
return textBox1.Location;
}
set
{
textBox1.Location = value;
}
}
[Description("Set Password Character Input in Textbox")]
public char PasswordChar
{
get
{
return textBox1.PasswordChar;
}
set
{
textBox1.PasswordChar = value;
}
}
[Description("Set the Multiline feature of Textbox")]
public bool MultiLine
{
get
{
return textBox1.Multiline;
}
set
{
textBox1.Multiline = value;
}
}
public CustomTextbox()
{
InitializeComponent();
}
}
}
I had declare an enum name direction so that i can change the position of label control as per value selected in Property Grid (left, right, down, up) and as per selected value label should align in project where i used the control dll.
Similarly i also want to create events for textbox like text validating and other important events of the controls.
How can i do this. Please suggest?

As par my understanding you need your own custom event from user control.
First define delegates and events in your user control as follow.
public delegate void TextChangeDelegate(object obj, string str);
public event TextChangeDelegate TextChanged;
Now in your user control you need to rise this event from your custom condition.
if(this.TextChanged != null)
{
this.TextChanged.Invoke(this, textBox1.Text);
}
Use this in you form where you use this as follow.
userControl.TextChanged += UserControl_TextChanged;

Related

Cannot declare a UserControl in file code

I have had a problem. I create an UserControl and I save it, it appears in ToolBox. I can drop it from ToolBox normally. However, I can not declare it as a variable in the file code. Can you help me, please? And it is file code of UserControl
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 Music_Player_Project_IT008N13.Controls;
namespace Music_Player_Project_IT008N13.Music_design_User_Control
{
public partial class LocationPanel : UserControl
{
public LocationPanel()
{
InitializeComponent();
}
public delegate void DoEvent(string maSo, string tenSV, string khoa, string diemTB);
public event DoEvent RefeshDgv;
private void btnDelete_Click(object sender, EventArgs e)
{
}
}
}
When you "drop it from the ToolBox normally", the Designer generates a member declaration for a new user control and also adds it to the forms Control collection. As I understand it, your question states that you would like to declare your user control variable in code. If this is the goal, we have to do the same thing that the Designer would do and add it to the Controls collection of the container you want to put it in.
Example
Add a FlowLayoutPanel using code, then add 3 CustomUserControls to it also in code.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Declare a flow layout panel in code.
// Add it to the main form control collection
var flowLayoutPanel = new FlowLayoutPanel
{
Name = "flowLayoutPanel",
Dock = DockStyle.Fill,
};
this.Controls.Add(flowLayoutPanel);
for (char c = 'A'; c < 'D'; c++)
{
var userControl = new CustomUserControl
{
Name = $"userControl{c}", // No space, start with lowercase
Text = $"UserControl {c}", // Visible name
Margin = new Padding(10, 2, 10, 2),
Width = flowLayoutPanel.Width - 20,
};
flowLayoutPanel.Controls.Add(userControl);
}
// T E S T
CustomUserControl? loopback = GetUserControl("userControlA");
Debug.Assert(loopback != null, "Expecting to retrieve user control by name");
}
Then, to use the control, retrieve it from the Controls collection by name.
CustomUserControl? GetUserControl(string name)
{
var layoutPanel = Controls["flowLayoutPanel"] as FlowLayoutPanel;
return layoutPanel.Controls[name] as CustomUserControl;
}
}
Where:
public partial class CustomUserControl : UserControl
{
public CustomUserControl() => InitializeComponent();
public new string Text
{
get => label1.Text;
set => label1.Text = value;
}
}

Textbox readonly property not working in TextBox made by me

I have a textbox (TextBoxMoeda) made by me, but, even when the textbox property readonly is set true. nothing happens. Anyone knows how to implement the code to resolve this problem?. Please help me?
public class TextBoxMoeda : TextBox
{
private double dp;
private string fmt = string.Empty;
private int _CasasDecimais = 0;
[Category("TextBoxMoeda")]
public virtual bool SomenteLeitura
{
get => base.ReadOnly;
set
{
base.ReadOnly = value;
Invalidate();
}
}
//Code Continues .......
}
WPF
You want the IsReadOnly property, not the ReadOnly property.
For example:
Create a new WPF App (.NET Framework) project called DeleteMe
In MainWindow.xaml, delete the Grid
In MainWindow.xaml.cs, use this code:
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace DeleteMe
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var tm = new TextBoxMoeda();
this.AddChild(tm);
tm.SomenteLeitura = true;
}
public class TextBoxMoeda : TextBox
{
[Category("TextBoxMoeda")]
public virtual bool SomenteLeitura
{
get => base.IsReadOnly;
set
{
base.IsReadOnly = value;
}
}
}
}
}
The textbox will be readonly (i.e. I can't type anything into the textbox).
WinForms
The code already appears to work in WinForms. These steps will produce a working project:
Create a new Windows Forms App project called DeleteMeAgain
Overwrite all of the Form1.cs code with this:
using System.ComponentModel;
using System.Windows.Forms;
namespace DeleteMeAgain
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var tm = new TextBoxMoeda();
this.Controls.Add(tm);
tm.SomenteLeitura = true;
}
public class TextBoxMoeda : TextBox
{
[Category("TextBoxMoeda")]
public virtual bool SomenteLeitura
{
get => base.ReadOnly;
set
{
base.ReadOnly = value;
Invalidate();
}
}
}
}
}
The textbox will be readonly (i.e. I can't type anything into the textbox).
Windows Form: User Control
Do this:
Create a new Windows Forms App called DeleteMe3
Set Target Framework to .NET Core 3.1 (Long-term support)
In your project, create a new UserControl with the filename TextBoxStack.cs
Overwrite all of the code for that user control with this:
using System.ComponentModel;
using System.Windows.Forms;
namespace DeleteMe3
{
public partial class TextBoxStack : TextBox
{
[Category("TextBoxStack")]
public virtual bool SomenteLeitura
{
get => base.ReadOnly;
set
{
base.ReadOnly = value;
Invalidate();
}
}
}
}
An error will appear. Go to the source of the error and delete that line.
Build the solution
Add your new user control to Form1
Select the new user control on the form
Change the SomenteLeitura property to True
Run the project. The textbox should be grey and readonly.

How to get a C# Custom TextBox to change cursor location on mouse click

I have a custom textbox, which is just a standard textbox with a couple additional small features, and it all works as expected. The problem I am having is that clicking in the field to change the cursor location does not actually change the location of the cursor, the cursor just stays at the beginning of the field.
Below is the code I am working with, I am hoping someone will be able to tell me what I am missing:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Test.UI.Controls
{
public partial class TestTextBox : TextBox
{
private Color normalForegroundColor = Color.Gray;
private Color textChangedForegroundColor = Color.Red;
private string startingText = string.Empty;
[Description("TextBox border color when text is changed"), Category("Appearance")]
public Color TextChangedColor
{
get { return textChangedForegroundColor; }
set { textChangedForegroundColor = value; }
}
[Description("Set starting text of textbox, as well as the Text property"), Category("Appearance")]
public String StartingText
{
get { return startingText; }
set
{
startingText = value;
this.Text = startingText;
}
}
public TestTextBox()
{
InitializeComponent();
normalForegroundColor = this.ForeColor;
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
this.ForeColor = this.Text == startingText ? normalForegroundColor : textChangedForegroundColor;
}
}
}
Below is a screen grab of what the custom textbox looks like with data in it:

Using custom color picker dialog in PropertyGrid

In PropertyGrid default color picker dialog not allow to set alpha value of color.
I already made my own color picker dialog and want to use it in PropertyGrid but not sure how to do it.
I managed to use my custom color picker dialog in property grid and copying code of it here in case some need it too:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace HelpersLib
{
public class MyColorEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (value.GetType() != typeof(RGBA))
{
return value;
}
IWindowsFormsEditorService svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (svc != null)
{
using (DialogColor form = new DialogColor((RGBA)value))
{
if (svc.ShowDialog(form) == DialogResult.OK)
{
return form.NewColor.RGBA;
}
}
}
return value;
}
public override bool GetPaintValueSupported(ITypeDescriptorContext context)
{
return true;
}
public override void PaintValue(PaintValueEventArgs e)
{
using (SolidBrush brush = new SolidBrush((RGBA)e.Value))
{
e.Graphics.FillRectangle(brush, e.Bounds);
}
e.Graphics.DrawRectangleProper(Pens.Black, e.Bounds);
}
}
}
And this is how it looks in property grid:
When i click button of it, it will open custom color dialog.
But still have one problem which i can't solve.
I can't use Color struct with this UITypeEditor, therefore created RGBA class.
When i use color struct, it look like this:
I will open another question for it i guess: Custom ColorEditor does not work properly on Color struct
To interact with PropertyGrid, you have to create your own "property class" (as described here). You can customise different parts and thus there are multiple solutions for what you want. As a first approach to your problem, here you have a code for propertyGrid1:
Property curProperty = new Property();
propertyGrid1.SelectedObject = curProperty;
Where Property is defined by:
public class Property
{
private ColorDialog _dialog = new customColorDialogDialog();
public ColorDialog dialog
{
get { return _dialog; }
set { _dialog.ShowDialog(); }
}
}
class customColorDialogDialog : ColorDialog
{
}
In this code, your color dialog (customColorDialogDialog) is triggered when clicking on the cell on the right hand side of the property name ("dialog").

Changes in my userControl are erased when I rebuild in Visual Studio (designer view)

This is my navigationItem.cs user control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Uboldi.Helpers;
namespace Uboldi
{
public partial class NavigationItem : UserControl
{
public bool IsSelected { get; set; }
private string _linkText = String.Empty;
[Browsable(true)]
public string LinkText
{
get { return this._linkText; }
set
{
this._linkText = value;
RefreshDisplay();
}
}
public NavigationItem()
{
InitializeComponent();
RefreshDisplay();
}
private void RefreshDisplay()
{
if (IsSelected)
this.BackColor = CustomizationHelper.GetSecondaryColor();
else
this.BackColor = CustomizationHelper.GetPrimaryColor();
lblText.Text = Text;
}
}
}
My intention is to use this in another usercontrol called NavigationBar.
While I CAN see the LinkText attribute of the NavigationItem.cs class, when I change it from the properties pane, a warning pops up:
Warning 1 You must rebuild your
project for the changes to
Uboldi.LeftNavigationbar to show up in
any open designers.
Fair enough, I rebuild, and then the changes I just typed in are gone!
Any ideas why?
Thank you for your time.
Perhaps your changes are not persisted by the designer.
Did you try using DesignerSerializationVisibilityAttribute?
http://msdn.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute.aspx
This is old but doesn't have an answer. Here is what I found that works. Hopefully this helps someone else.
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Description("Test text displayed in the link"), Category("Data")]
public string LinkText
{
get { return this._linkText; }
set
{
this._linkText = value;
RefreshDisplay();
}
}

Categories