How to simulate pressing f2 to make treeview node editable - c#

I'm using radtreeview control from Telerik Q3 2010 for winForms and I want to do the following, upon addition of a new node it should be added in Edit mode, well this is not supported in telerik 2010 so I need to simulate pressing F2 to make the node editable.
I found this thread about the same topic: How to simulate pressing F2 button with keyboard focus on treeview in wpf?, but I need to do that in Winform not WPF, can you help me?
Edit
I used sendKeys method + tree.BeginEdit but it didn't work out !
This is my code:
private void radButton6_Click(object sender, EventArgs e)
{
RadTreeNode newNode = new RadTreeNode();
newNode.Text = "new Cabinet";
newNode.Tag = "new Cabinet";
cabinetsTree.Nodes.Add(newNode);
cabinetsTree.SelectedNode = cabinetsTree.Nodes[cabinetsTree.Nodes.Count-1];
cabinetsTree.ScrollToBottom(); //To set the focus on the new added node
cabinetsTree.Focus();
cabinetsTree.AllowEdit = true;
SendKeys.Send("{F2}");
cabinetsTree.BeginEdit();
}

You should first allow editing nodes in the control and then use the BeginEdit method of the node:
public partial class Form1 : Form
{
RadTreeView tree = new RadTreeView();
public Form1()
{
InitializeComponent();
this.Controls.Add(tree);
tree.Size = new Size(500, 500);
tree.AllowEdit = true;
}
private void button1_Click(object sender, EventArgs e)
{
RadTreeNode newNode = new RadTreeNode();
newNode.Text = "new Cabinet";
tree.Nodes.Add(newNode);
newNode.BeginEdit();
}
}

The node should have a BeginEdit() method that allows the user to rename the node. Based on the documentation.
Use the BeginEdit() method to initiate editing on the selected node

You might be able to solve this by catching the keypress events on your keyboard and setting the editmode to true whenever you get the f2 key pressed.

Related

C# - How to choose which Control User load first?

I'm using WinForm to do my little CRM.
I got MainWindow form and on this form 3 panels ( 1 Top/ 1Left/ the other part is filled up by 7 Control User )
All the Control User are on top of each other, and when i click on some button( attached to the left panel) the called CU is brought to the front.
public void BtnContact_Click(object sender, EventArgs e)
{
contactControl1.Visible = true;
contactControl1.BringToFront();
panelBar.Height = BtnContact.Height;
panelBar.Top = BtnContact.Top;
employe1.Visible = false;
comptaControl1.Visible = false;
histoControl1.Visible = false;
alerteControl1.Visible = false;
voyageursControl1.Visible = false;
parametresControl1.Visible = false;
}
I don't want all the CU to load at the start of the App, but i want them to be launch when i click on the button on the left. And let say if i opened one and now opening a new one it close the one who was opened.
If i have no choice to open everything ( which i doubt ) how can i choose the one i want to open first or second etc ??
Thank you
I don't want all the CU to load at the start of the App
Use properties tab and make visible=false or use formload event to prevent all cu loading at the start.
private void Form1_Load(object sender, System.EventArgs e)
{
//use code to make anything visible or invisible
}
you can put all controls that should be shown or hidden on the panel.
This is called the other part is filled up by 7 Control User in the question, so just use Panel to store all those controls.
Then you can introduce new field on your form to store current control index that is shown and to write button click that will check the index and activate next control
int currentIndex = -1;
public void BtnContact_Click(object sender, EventArgs e)
{
currentIndex++;
if (currentIndex >= panelFor7Control.Controls.Count)
currentIndex = 0;
foreach (Control c in panelFor7Control.Controls)
c.Visible = false;
Control control2show = panelFor7Control.Controls[currentIndex] ;
control2show.Visible = true;
}
Button BtnContact has to be pressed to activate next control on the panel.
PS I suppose that you are trying to load data for the visible control only. You can use Control.VisibleChanged to check is data loaded and to load if control is visible and data was not loaded.
First you need to make instance of your UC, something like this:
public partial class YourUC : UserControl
{
public static YourUC _instance;
public static YourUC Instance
{
get
{
if (_instance == null)
_instance = new YourUC();
return _instance;
}
}
}
Then you need to call and show UC when button is clicked
private void btn_Click(object sender, EventArgs e)
{
if (!pnlControls.Controls.Contains(YourUC.Instance))
{
pnlControls.Controls.Add(YourUC.Instance);
YourUC.Instance.Dock = DockStyle.Fill;
YourUC.Instance.BringToFront();
}
else
{
YourUC.Instance.BringToFront();
}
}
You it sounds like you want to have a "pages" navigation, I'm not use to work with WinForm, but perhaps this post could help you
What is the most efficient way to create a Win form with multiple pages?
It seems that you have to manage what Control you want to display manually.
Note that passing Controls from Visible to Hidden doesn't unload them

ToolStripMenuItem ShowDropDown - event doesn't fire

I want to put a context sensitive menu on the right-click of a DataGridView. I want to have a single menu item derived from the content of the clicked cell and a variable number of items in a sub-menu, retrieved from a database.
I do this by building the ToolStripMenuItem in the ContextMenuStrip Opening event. And it works - almost...
If I leave the sub-menu undisplayed so the user has to click the single item in the toplevel menu, everything is fine but if I call the ShowDropDown method to display the submenu automatocally, the exents don't fire when the items are clicked on.
Here's the simplest code I can produce to recreate the problem - I've pulled out all the references to the DataGridView and database so my "dynamic" menu is decidedly static ;-)
If you put this is a Form definition, right-click anywhere on the form and you'll see the working but not desired behaviour - click on a sub-menui tem and see a popup. Tick the checkbox and right-click again and you'll see the submenu flies out automatically - but clicking items won't fire the aliasClick handler.
Any thoughts? In this particular application, I can code a perfectly servicable workaround which avoids using ShowDropDown - but I'd like to know what I'm doing wrong in case I need to use it in future.
public partial class Form1 : Form
{
private ContextMenuStrip cms;
private CheckBox chkAuto;
public Form1()
{
InitializeComponent();
chkAuto = new CheckBox();
Controls.Add(chkAuto);
cms = new ContextMenuStrip();
cms.Opening += contextMenuStrip1_Opening;
this.MouseClick += Form1_MouseClick;
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
cms.Show(Cursor.Position);
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
cms.Items.Clear();
ToolStripMenuItem tsmi = new ToolStripMenuItem("Title from datagridviewcell");
tsmi.DropDownItems.Add(new ToolStripMenuItem("First item from database lookup", null, aliasClick));
tsmi.DropDownItems.Add(new ToolStripMenuItem("Second item from database lookup", null, aliasClick));
tsmi.DropDownItems.Add(new ToolStripMenuItem("Last item from database lookup", null, aliasClick));
cms.Items.Add(tsmi);
if (chkAuto.Checked)
tsmi.ShowDropDown();
e.Cancel = false;
}
private void aliasClick(object sender, EventArgs e)
{
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
MessageBox.Show(clickedItem.Text);
}
}
I'm not entirely sure how to go about proving this, but I suspect that your call to tsmi.ShowDropDown() is somehow causing the coordinates to not be captured properly by the click handler. Replace it with cms.Show(MousePosition) and it works.
Perhaps some useful info gleaned from a look at the coordinates...
var mi = new ToolStripMenuItem("First item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi);
var mi2 = new ToolStripMenuItem("Second item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi2);
var mi3 = new ToolStripMenuItem("Last item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi3);
cms.Items.Add(tsmi);
if (chkAuto.Checked)
tsmi.ShowDropDown();
//cms.Show(MousePosition);
Debug.WriteLine(mi.Bounds.ToString());

Enabling/disabling button

I am having trouble getting my 'start' button to show when I select either of the radio boxes.
Ideally, when one of the boxes is selected, the 'start' button will enable and allow to be clicked.
Here is my code for the form, as I am relatively new to C# I'm not sure if I'm posting all of the code you need, I'll post more if required.
public partial class mainForm : Form
{
public mainForm() {
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e) {
}
private void mainForm_Load(object sender, EventArgs e) {
title.Font = new Font("Arial", 10, FontStyle.Bold);
}
private void startButton_Click(object sender, EventArgs e) {
if (radioDice.Checked) {
startButton.Enabled = true; //Activates 'start' button
whichDiceGameForm GameForm = new whichDiceGameForm();
GameForm.Show();
}
if (radioCard.Checked) {
startButton.Enabled = true; //Activates 'start' button
whichCardGame GameForm = new whichCardGame();
GameForm.Show();
}
}
}
[Posting for a friend.]
You have placed your enable code in the Button's Click event Handler while you should do it on your checkboxes changed.
Take this code :
if (radioDice.Checked)
{
startButton.Enabled = true;
}
to radioDice checkbox's changed event handler and this one :
if (radioCard.Checked)
{
startButton.Enabled = true; //Activates 'start' button
}
to radioCard checkbox's changed event handler .
Man, seriously?
ANSWER:
You're trying to enable DISABLED button when clicking on that button. You cannot click DISABLED button. What's more - you're duplicating your code.
Button should be always enabled. You only have two choices. Every choice enabled button. So it should be always enabled. No matter the choice. If there is something hidden and button may be disabled, then enable the button in Radio Click event.
Additional information about your code:
Now. About code duplication. Look what you're doing in startButton_Click. You have duplicated code.
You can do something like:
BaseGameForm f = null;
if(radioDice.Checked)
f = new DiceGameForm();
else
if(radioCard.Checked)
f = new CardGameForm();
f.Show();
(BaseGameForm is base form for every game)
But this is not good solution. Better solution is (somewhere in construtor):
radioDice.Tag = new DiceGameForm();
radioCard.Tag = new CardGameForm();
Then in Start button click you look for checked radio:
foreach(Control c in selectGameTypeGroupBox.Controls) //you could do this using LINQ
{
if((c is RadioButton) && ((RadioButton)c).Checked)
{
((Form)c.Tag).Show();
}
}
But this is still not good solution, because you're creating all game forms at startup and this is stupid.
So the better solution would be to keep game form class name in your radio Tag property and then create object of this class using reflection and Activator.
But this is still not the best solution. But I assume that this is one of your first applications so I won't be telling you now about separating gui from logic. If you want to know more - read on the Internet. Or just ask.

Main form is always stealing focus, when child form is created out of treeView

I've the following problem:
My program (Winforms) has a main window with a treeView control.
When the user selects a node in the treeView a new child window shall be created.
This works just fine.
But the problem is, that after this child window has become visible, the main window comes to front and partially hides this child window.
I've build a little mockup in order to make sure that it is not only related to my program:
namespace FatherAndSon
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Son aNewSon = new Son();
aNewSon.Visible = true;
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
Son aNewSon = new Son();
aNewSon.Visible = true;
}
}
}
When I press the button1, all is fine but when I select a node in the treeView, the main window jumps to the front immediately after the child form appeared.
What is wrong?
Change Visible = true to .Show(this) -> this change will make that child window will always be on top of it's Parent (main window in this case).
Son aNewSon = new Son();
aNewSon.Show(this);
if it is not acceptable that child form is always on top of it's parent then change it to:
Son aNewSon = new Son();
aNewSon.Visible = true;
aNewSon.Focus();
To have "aNewSon" always on top, you can also try to add the "TopMost" property to the newly created form:
aNewSon.TopMost = true;
Check Msdn about TopMost property.
Add the parent form to the constructor try use "Show" method instead of visible=true.
Son aNewSon = new Son();
aNewSon.Show(this);
may be, than you can also call BringToFront method Application.OpenForms["Form1"].BringToFront();
in your case:
Son aNewSon = new Son();
aNewSon.Show(this);
aNewSon.BringToFront();

C# Web Browser with click and highlight

Before I go off and code this, I thought I'd see if anyone here knows of any open source (or paid for) equivalents already built.
I'm looking for a browser control where users can preview a web page and then highlight elements of it and once highlighted, I can get the div or id of the element selected.
Has anyone seen such a thing?
Here's a crude version using the .NET WebBrowser control, which uses Internet Explorer.
namespace WindowsFormsApplication1
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
public partial class Form1 : System.Windows.Forms.Form
{
private HtmlDocument document;
private IDictionary<HtmlElement, string> elementStyles = new Dictionary<HtmlElement, string>();
public Form1()
{
InitializeComponent();
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.Text = e.Url.ToString();
this.document = this.webBrowser1.Document;
this.document.MouseOver += new HtmlElementEventHandler(document_MouseOver);
this.document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave);
}
private void document_MouseLeave(object sender, HtmlElementEventArgs e)
{
HtmlElement element = e.FromElement;
if (this.elementStyles.ContainsKey(element))
{
string style = this.elementStyles[element];
this.elementStyles.Remove(element);
element.Style = style;
}
}
private void document_MouseOver(object sender, HtmlElementEventArgs e)
{
HtmlElement element = e.ToElement;
if (!this.elementStyles.ContainsKey(element))
{
string style = element.Style;
this.elementStyles.Add(element, style);
element.Style = style + "; background-color: #ffc;";
this.Text = element.Id ?? "(no id)";
}
}
}
}
I had a similar need and the code originally posted was a tremendous help. I would like to return the kindness of the original author.
The answer provided is insufficient. It only answers the first part of the request: highlighting the rendered HTML. It does not solve the second half of the request where the C# program can tell which node is selected.
As the mouse enters the form and moves towards the desired rendered area, the highlight will follow the mouse. This means that potentially many HTML elements will be visited by the mouse.
So how can the C# tell which element the user wants?
The program has to allow the user to click on the desired rendered area. The click should be trapped by the C# program. In addition, the C# should disable the click being delivered to the element (for example, if its an Anchor element you don't want the click to follow the link).
I solved this in my program as follows:
(1) On the 'document complete' event I added a trap (only once for the document) for the click event at the document level:
HtmlDocument htmlDoc = webBrowser.Document;
_document = webBrowser.Document;
//-- add our handler only once
if (!_documentHandlers.Contains(_document))
{
_document.MouseOver += new HtmlElementEventHandler(document_MouseOver);
_document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave);
mshtml.HTMLDocumentEvents2_Event iEvent;
IHTMLDocument2 currentDoc = (IHTMLDocument2) webBrowser.Document.DomDocument;
iEvent = (mshtml.HTMLDocumentEvents2_Event) currentDoc;
iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(clickDocumentHandler);
_documentHandlers.Add(_document);
}
The 'document completed' event can be triggered several times for the same document (try CNN.com). The '_documentHandlers' variable is a HashSet to make sure we only add the handler one time per a given document.
(2) I also chose to trap the click at the element level. On the 'mouse over' I added:
mshtml.HTMLElementEvents2_Event iEvent;
iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event;
if (iEvent == null)
return;
iEvent.onclick += new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler);
and at the 'mouse leave' I unregistered the click handler:
mshtml.HTMLElementEvents2_Event iEvent;
iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event;
if (iEvent == null)
return;
iEvent.onclick -= new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler);
(3) the click handlers are simple:
private bool clickDocumentHandler(IHTMLEventObj pEvtObj)
{
IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement;
pEvtObj.cancelBubble = true;
pEvtObj.returnValue = false;
return false;
}
private bool clickElementHandler(IHTMLEventObj pEvtObj)
{
IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement;
pEvtObj.cancelBubble = true;
pEvtObj.returnValue = false;
return false;
}
Note that they cancel the bubbling of event and return a value of 'false' to prevent the click from percolating upwards.
In these handlers you can add your specific code to save the element being clicked and then use it elsewhere in your application.
Note that at the element level, not every IHTMLElement supports an onclick handler hence the check for null.
-Enjoy
David

Categories