How can I get PropertyGrid's TextBox from specified field?
I need this TextBox to set Pointer to the end of text.
var num = txtBox.GetCharIndexFromPosition(Cursor.Position);
txtBox.SelectionStart = num + 1;
txtBox.SelectionLength = 0;
So how can I get this TextBox from PropertyGrid?
Also, property in PropertyGrid is read-only.
If what you want is the cursor to be located right after the last character written in the textbox, you can rely on the following code (triggered by the TextChanged Event of the TextBox):
private void txtBox_TextChanged(object sender, EventArgs e)
{
int newX = txtBox.Location.X + TextRenderer.MeasureText(txtBox.Text, txtBox.Font).Width;
int newY = txtBox.Bottom - txtBox.Height / 2;
if (newX > txtBox.Location.X + txtBox.Width)
{
newX = txtBox.Location.X + txtBox.Width;
}
Cursor.Position = this.PointToScreen(new Point(newX, newY));
}
Bear in mind that its Y position is always in the middle.
----- UPDATE AFTER THE KINGKING COMMENT
As far as the code in the question was referred to the TextBox, I focused my answer on the TextBox. Nonetheless, KingKing is right and the PropertyGrid has to be brought into consideration. Below these lines I adapted the code you can find in MSDN for PropertyGrid:
private void Form1_Load(object sender, EventArgs e)
{
PropertyGrid propertyGrid1 = new PropertyGrid();
propertyGrid1.CommandsVisibleIfAvailable = true;
propertyGrid1.Location = new Point(10, 20);
propertyGrid1.Size = new System.Drawing.Size(400, 300);
propertyGrid1.TabIndex = 1;
propertyGrid1.Text = "Property Grid";
this.Controls.Add(propertyGrid1);
propertyGrid1.SelectedObject = txtBox;
}
After txtBox is added to propertyGrid1, its position is updated and thus the original code can be used without any problem.
In summary, the idea is not looking for the TextBox inside the PropertyGrid, but accessing directly the TextBox control (which is added at runtime to the PropertyGrid).
Related
I am new to C# and want to change the size of some Pictureboxes based on one trackbar Value.
If i write the below code refering to a spesific picturebox (e.g. Picturebox1 instead of PB) it works, but i would like to use one Doubleclick event for all Pictureboxes that i Doubleclick.
The below code gives PB = null.
I get the selected Pictureboxname but how can i refer to this Picturebox?
'''
private void PictureBoxesDoubleClick(object sender, EventArgs e)
{
//get the selected Picturebox name
String PictureBoxName = ((PictureBox)sender).Name;
//This part doesn't work
PictureBox PB = (PictureBox)this.Controls[PictureBoxName];
//Resize the Picture box according to the trackBar Value
PB.Size = new Size(trackBar1.Value, trackBar1.Value);
PB.Left = (this.ClientSize.Width - pictureBox1.Width) / 2;
PB.Top = (this.ClientSize.Height - pictureBox1.Height) / 2;
}
'''
Which pictureBox was selected? C#
Thank you
This is the common function which I used for the two picture boxes on their double click and it is working fine. Check if you also had a common function for all the picture boxes in the form.
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
//get the selected Picturebox name
String PictureBoxName = ((PictureBox)sender).Name;
PictureBox PB = (PictureBox)this.Controls[PictureBoxName];
//Resize the Picture box according to the trackBar Value
PB.Size = new Size(trackBar1.Value*10, trackBar1.Value*10);
PB.Left = (this.ClientSize.Width - pictureBox1.Width) / 2;
PB.Top = (this.ClientSize.Height - pictureBox1.Height) / 2;
}
I created an textbox from code behind like this:
TextBox txtPlainTxt = new TextBox();
txtPlainTxt.Height = 200;
txtPlainTxt.Width = 300;
txtPlainTxt.TextWrapping = TextWrapping.Wrap;
txtPlainTxt.Text = text;
int lineCount = txtPlainTxt.LineCount;
I'm trying to get the LineCount property of a textbox but problem is that it always has the value of "-1". I guess it have something to do with that I created it from code behind and not in my xaml becouse when I create the exact same textbox in xaml, everything works fine and I get the correct number of lines in it.
I tried to call UpdateLayout() method and also tried to call Focus() method like this:
txtPlainTxt.Focus();
txtPlainTxt.UpdateLayout();
txtPlainTxt.Focus();
txtPlainTxt.UpdateLayout();
But I still get the value of -1. How can I solve this problem?
That is happening because until your layout gets measured, you don't have ActualHeight and ActualWidth, so LineCount can't get calculated until that happens.
That means that you can only use LineCount property after your layout got measured & arranged.
(UpdateLayout() only notifies the layout engine that the layout should be updated and immediately returns.)
public partial class Window1 : Window
{
TextBox txtPlainTxt = new TextBox();
public Window1()
{
txtPlainTxt.Height = 200;
txtPlainTxt.Width = 300;
txtPlainTxt.TextWrapping = TextWrapping.Wrap;
txtPlainTxt.Text = "some text some text some text some text some text";
Grid.SetRow(txtPlainTxt, 0);
Grid.SetColumn(txtPlainTxt, 0);
gridMain.Children.Add(txtPlainTxt);
// here it will be -1
int lineCount = txtPlainTxt.LineCount;
gridMain.LayoutUpdated += new EventHandler(gridMain_LayoutUpdated);
txtPlainTxt.LayoutUpdated += new EventHandler(txtPlainTxt_LayoutUpdated);
}
void txtPlainTxt_LayoutUpdated(object sender, EventArgs e)
{
// the layout was updated, LineCount will have a value
int lineCount = txtPlainTxt.LineCount;
}
void gridMain_LayoutUpdated(object sender, EventArgs e)
{
// here it will be correct too
int lineCount = txtPlainTxt.LineCount;
}
}
I'm working on a mind-map project. I'm trying to get the "New Bubble" button to create a new textbox into a FREE space on the form. So I want to check if there is another bubble in the place where it's getting created. If it already has a textbox then I want it to find a new place and repeat the process.
How can I do this?
public partial class frmMap : Form
{
private void btnProperties_Click(object sender, EventArgs e)
{
new frmProperties().Show();
}
private void btnNewBubble_Click(object sender, EventArgs e)
{
var tb = new TextBox();
tb.Multiline = true;
tb.BorderStyle = BorderStyle.FixedSingle;
tb.Top = 100;
tb.Left = 200;
tb.Size = new Size(100, 100);
this.Controls.Add(tb);
}
}
You can check "collision" with other controls like so:
foreach (Control checkControl in Controls)
{
if (tb.Bounds.IntersectsWith(checkControl.Bounds))
...
}
Of course, thats a lot of checking to do! If you are just going to "grid" the controls, it would be faster/easier to just layout a bool array that holds the state of each "cell" (filled/empty) then pick the first empty one you find.
Create dynamic textbox:
var tb = new TextBox();
tb.Multiline = true;
tb.BorderStyle = BorderStyle.FixedSingle;
tb.Top = 100;
tb.Left = 200;
tb.Size = new Size(100, 100);
Then use Rectangle.IntersectWith to check if new textbox intersects with other already added texboxes (you can remove control type filter, if you have other type of controls to check):
while(Controls.OfType<TextBox>().Any(x => tb.Bounds.IntersectsWith(x.Bounds))
{
// adjust tb size or position here
}
And last step - add textbox to form:
Controls.Add(tb);
I'm working with .NET forms in Visual C#.
I've created a label dynamically, which shows upon a button click. This all works fine; what I'm trying to do is position it so that the element is at the centre of the form. Normally, I'd just set it to half the form size, minus half the element size, but of course this won't work as I am setting the text programmatically also.
My code for the label is as follows:
if(part == 1){
theLabel.Text = "Choose a name for your character!";
}
theLabel.ForeColor = Color.DarkGray;
theLabel.Font = new Font("Arial", 14, FontStyle.Bold);
theLabel.Location = new Point();
I've tried many things here, but I just cannot think of a way. I've tried int[] sizes = (int)theLabel.Size and various other but I just cannot get this to work. Is there another way to line this element to the middle?
If I was you I'd do it this way.
Label theLabel;
private void button1_Click(object sender, EventArgs e)
{
theLabel = new Label();
theLabel.AutoSize = true;
theLabel.BackColor = Color.Red;
theLabel.TextAlign = ContentAlignment.MiddleCenter;
theLabel.Text = "Choose a name for your character!";
this.Controls.Add(this.theLabel);
theLabel.Left = (this.ClientRectangle.Width - theLabel.Width) / 2;
//theLabel.ForeColor = Color.Black;
theLabel.Top = 25;
theLabel.Show();
}
When I add my controls to the form, it goes fine until I try to specify a location larger than int16.MaxValue. The controls just pile up on top of each other. Here is code which is simplified but demonstrates the behavior:
private void Form1_Load(object sender, EventArgs e)
{
this.AutoScroll = true;
int nexttop = 0;
for (int i = 0; i < 500; i++)
{
TextBox t = new TextBox();
t.Text = i.ToString();
t.Multiline = true;
if (nexttop > Int16.MaxValue)
{
bool debug = true;
}
t.Location = new Point(0, nexttop);
t.Size = new Size(100, 77);
nexttop += t.Height;
this.Controls.Add(t);
}
}
I want to avoid moving the scroll bar programaticaly, since this causes timing issues.
Do you have any ideas on how to fix this? TIA.
This limit (32767) is due to GDI+. I believe different behaviours may be observed according to the Windows version.