treeview AfterLabelEdit MessageBox displays twice - c#

I am playing with Treeview and the AfterLabelEdit function and IM having a problem where after validation it displays the MessageBox Twice before it goes back to Editing. Anyone see what I might be doing wrong here.
private void treeView1_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
{
var HostsXML = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hosts.xml");
XmlDocument doc = new XmlDocument();
doc.Load(HostsXML);
foreach (TreeNode pChild in e.Node.Parent.Nodes)
{
if (pChild.Text == e.Label)
{
// same name found, cancel the edit operation
MessageBox.Show("That Name Cannot be Used. Please Select a Different Name");
e.CancelEdit = true;
e.Node.BeginEdit();
//treeView1.Nodes.Remove(treeView1.SelectedNode);
return;
}
}
if (e.Label != null)
{
if (e.Label.Length > 0)
{
if (String.IsNullOrEmpty(selectedNode))
{
XmlNode rootNode = doc.SelectSingleNode("Servers");
XmlNode recordNode = rootNode.AppendChild(doc.CreateNode(XmlNodeType.Element, "Server", ""));
recordNode.AppendChild(doc.CreateNode(XmlNodeType.Element, "Name", "")).InnerText = e.Label;
}
else
{
XmlElement root = doc.DocumentElement;
XmlNodeList xnList = doc.SelectNodes("/Servers/Server[Name ='" + selectedNode + "']");
foreach (XmlNode xn in xnList)
{
xn["Name"].InnerText = e.Label;
}
}
}
else
{
MessageBox.Show("You Did Not Enter a Valid Name:1");
e.CancelEdit = true;
e.Node.BeginEdit();
//treeView1.Nodes.Remove(treeView1.SelectedNode);
return;
}
}
else
{
e.CancelEdit = true;
MessageBox.Show("You Did Not Enter a Valid Name: 2");
e.Node.BeginEdit();
//treeView1.Nodes.Remove(treeView1.SelectedNode);
return;
}
selectedNode = null;
doc.Save(HostsXML);
}

Related

Update XLSX file changes whilst reading the file with XmlReader

We had a code which was loading the Excel XLSX document into the memory, doing some modifications with it and saving it back.
XmlDocument doc = new XmlDocument();
doc.Load(pp.GetStream());
XmlNode rootNode = doc.DocumentElement;
if (rootNode == null) return;
ProcessNode(rootNode);
if (this.fileModified)
{
doc.Save(pp.GetStream(FileMode.Create, FileAccess.Write));
}
This was working good with small files, but throwing OutOfMemory exceptions with some large Excel files. So we decided to change the approach and use XmlReader class to not load the file into the memory at once.
PackagePartCollection ppc = this.Package.GetParts();
foreach (PackagePart pp in ppc)
{
if (!this.xmlContentTypesXlsx.Contains(pp.ContentType)) continue;
using (XmlReader reader = XmlReader.Create(pp.GetStream()))
{
reader.MoveToContent();
while (reader.EOF == false)
{
XmlDocument doc;
XmlNode rootNode;
if (reader.NodeType == XmlNodeType.Element && reader.Name == "hyperlinks")
{
doc = new XmlDocument();
rootNode = doc.ReadNode(reader);
if (rootNode != null)
{
doc.AppendChild(rootNode);
ProcessNode(rootNode); // how can I save updated changes back to the file?
}
}
else if (reader.NodeType == XmlNodeType.Element && reader.Name == "row")
{
doc = new XmlDocument();
rootNode = doc.ReadNode(reader);
if (rootNode != null)
{
doc.AppendChild(rootNode);
ProcessNode(rootNode); // how can I save updated changes back to the file?
}
}
else
{
reader.Read();
}
}
}
}
This reads the file node by node and processes nodes we need (and changes some values there). However, I'm not sure how we can update those values back to the original Excel file.
I tried to use XmlWriter together with the XmlReader, but was not able to make it work. Any ideas?
UPDATE:
I tried to use #dbc's suggestions from the comments section, but it seems too slow to me. It probably will not throw OutOfMemory exceptions for huge files, but processing will take forever.
PackagePartCollection ppc = this.Package.GetParts();
foreach (PackagePart pp in ppc)
{
if (!this.xmlContentTypesXlsx.Contains(pp.ContentType)) continue;
StringBuilder strBuilder = new StringBuilder();
using (XmlReader reader = XmlReader.Create(pp.GetStream()))
{
using (XmlWriter writer = this.Package.FileOpenAccess == FileAccess.ReadWrite ? XmlWriter.Create(strBuilder) : null)
{
reader.MoveToContent();
while (reader.EOF == false)
{
XmlDocument doc;
XmlNode rootNode;
if (reader.NodeType == XmlNodeType.Element && reader.Name == "hyperlinks")
{
doc = new XmlDocument();
rootNode = doc.ReadNode(reader);
if (rootNode != null)
{
doc.AppendChild(rootNode);
ProcessNode(rootNode);
writer?.WriteRaw(rootNode.OuterXml);
}
}
else if (reader.NodeType == XmlNodeType.Element && reader.Name == "row")
{
doc = new XmlDocument();
rootNode = doc.ReadNode(reader);
if (rootNode != null)
{
doc.AppendChild(rootNode);
ProcessNode(rootNode);
writer?.WriteRaw(rootNode.OuterXml);
}
}
else
{
WriteShallowNode(writer, reader); // Used from the #dbc's suggested stackoverflow answers
reader.Read();
}
}
writer?.Flush();
}
}
}
NOTE 1: I'm using StringBuilder for the test, but was planning to switch to a temp file in the end.
NOTE 2: I tried flushing the XmlWriter after every 100 elements, but it's still slow.
Any ideas?
Try following. I've been use for a long time with huge xml files that give Out of Memory
using (XmlReader reader = XmlReader.Create("File Stream", readerSettings))
{
while (!reader.EOF)
{
if (reader.Name != "row")
{
reader.ReadToFollowing("row");
}
if (!reader.EOF)
{
XElement row = (XElement)XElement.ReadFrom(reader);
}
}
}
}
I did some more modifications with #dbc's help and now it works as I wanted.
PackagePartCollection ppc = this.Package.GetParts();
foreach (PackagePart pp in ppc)
{
try
{
if (!this.xmlContentTypesXlsx.Contains(pp.ContentType)) continue;
string tempFilePath = GetTempFilePath();
using (XmlReader reader = XmlReader.Create(pp.GetStream()))
{
using (XmlWriter writer = this.Package.FileOpenAccess == FileAccess.ReadWrite ? XmlWriter.Create(tempFilePath) : null)
{
while (reader.EOF == false)
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "hyperlinks")
{
XmlDocument doc = new XmlDocument();
XmlNode rootNode = doc.ReadNode(reader);
if (rootNode != null)
{
ProcessNode(rootNode);
if (writer != null)
{
rootNode.WriteTo(writer);
}
}
}
else if (reader.NodeType == XmlNodeType.Element && reader.Name == "row")
{
XmlDocument doc = new XmlDocument();
XmlNode rootNode = doc.ReadNode(reader);
if (rootNode != null)
{
ProcessNode(rootNode);
if (writer != null)
{
rootNode.WriteTo(writer);
}
}
}
else
{
WriteShallowNode(writer, reader); // Used from the #dbc's suggested StackOverflow answers
reader.Read();
}
}
}
}
if (this.packageChanged) // is being set in ProcessNode method
{
this.packageChanged = false;
using (var tempFile = File.OpenRead(tempFilePath))
{
tempFile.CopyTo(pp.GetStream(FileMode.Create, FileAccess.Write));
}
}
}
catch (OutOfMemoryException)
{
throw;
}
catch (Exception ex)
{
Log.Exception(ex, #"Failed to process a file."); // our inner log method
}
finally
{
if (!string.IsNullOrWhiteSpace(tempFilePath))
{
// Delete temp file
}
}
}

foreach isn't reading well through .descendants and goes to else statement before if

I'm still learning in terms of C#
I'm currently working on a filter system and have an if statement list that prevents user to from performing any actions. Now is it that whenever the user submits an ID, my foreach is supposed to run through the list of already submitted ID's checking whether they exist already or not.
The bug is that when the user submits an already existing ID, it will not see the existing ID in the first run so it will create and fill in a node, but in the second run it does so it sends an error message & breaks the session.
My code:
private async void btnAddId_Click(object sender, RoutedEventArgs e)
{
XmlDocument Xdoc = new XmlDocument();
Xdoc.Load(xmldoc);
XmlNode NodeEl = Xdoc.SelectSingleNode("root/filter/filter_item");
XmlNode NodeList = Xdoc.SelectSingleNode("root/filter");
var root = XDocument.Load(xmldoc).Root;
var filter = root.Element("filter");
int parsedValue;
foreach (var f in filter.Descendants())
{
if (f.Value == tbAddId.Text)
{
MessageBox.Show("Value already exists in the orderlist!");
}
else if (!int.TryParse(tbAddId.Text, out parsedValue))
{
MessageBox.Show("Input isn't numeric!");
}
else if (tbAddId.Text == "")
{
MessageBox.Show("No value was given!");
}
else if (tbAddId.Text == "Add ID")
{
MessageBox.Show("No value was given!");
}
else if (NodeList.InnerText == "")
{
NodeEl.InnerText = tbAddId.Text;
tbAddId.Text = "Add ID";
tbAddId.Foreground = Brushes.Gray;
await api.config_Load();
await api.Page_Load();
}
else
{
XmlNode filterItem = Xdoc.CreateElement("filter_item");
NodeList.AppendChild(filterItem);
filterItem.InnerText = tbAddId.Text;
}
tbOrderDisplay.Text += f.Value + " ";
}
Xdoc.Save(xmldoc);
}
XML content
<?xml version="1.0"?>
<root>
<bol_client_id></bol_client_id>
<!--- this is the client id-->
<bol_client_secret></bol_client_secret>
<!-- this is the client secret -->
<customer_id></customer_id>
<company_phone></company_phone>
<auth_token_url></auth_token_url>
<bol_orders_url></bol_orders_url>
<debug_mode>true</debug_mode>
<filter>
<filter_item>1172828940</filter_item>
<filter_item>1173700637</filter_item>
</filter>
</root>
Check whether value exists before you try to insert it:
private async void btnAddId_Click(object sender, RoutedEventArgs e)
{
XmlDocument Xdoc = new XmlDocument();
Xdoc.Load(xmldoc);
XmlNode NodeEl = Xdoc.SelectSingleNode("root/filter/filter_item");
XmlNode NodeList = Xdoc.SelectSingleNode("root/filter");
var root = XDocument.Load(xmldoc).Root;
var filter = root.Element("filter");
int parsedValue;
//1. Check for duplicates
foreach (var f in filter.Descendants())
{
if (f.Value == tbAddId.Text)
{
MessageBox.Show("Value already exists in the orderlist!");
tbOrderDisplay.Text += f.Value + " ";
return;
}
}
//2. Validate and insert
if (!int.TryParse(tbAddId.Text, out parsedValue))
{
MessageBox.Show("Input isn't numeric!");
}
else if (tbAddId.Text == "")
{
MessageBox.Show("No value was given!");
}
else if (tbAddId.Text == "Add ID")
{
MessageBox.Show("No value was given!");
}
else if (NodeList.InnerText == "")
{
NodeEl.InnerText = tbAddId.Text;
tbAddId.Text = "Add ID";
tbAddId.Foreground = Brushes.Gray;
await api.config_Load();
await api.Page_Load();
}
else
{
XmlNode filterItem = Xdoc.CreateElement("filter_item");
NodeList.AppendChild(filterItem);
filterItem.InnerText = tbAddId.Text;
}
Xdoc.Save(xmldoc);
}

C# code works when it hits breakpoint otherwise does not when i disable all breakpoint [Winforms]

My code below runs perfectly when i try to debug applying breakpoint but when i disable breakpoints and run it again, it does not work perfectly. Here i am creating a non-stock item, now when it navigates to other page it does not show all the inserted rows.
I tried to make submit call async and put SaveNonStockItems() in await but it did not work
private void btnSubmit_Click(object sender, EventArgs e)
{
StringBuilder quoteDetailIDs = new StringBuilder();
foreach (DataGridViewRow dataGridViewRow in grdQuoteDetail.Rows)
{
if (dataGridViewRow.Cells["colSelected"].Value != null &&
dataGridViewRow.Cells["colSelected"].Value != DBNull.Value &&
(bool)dataGridViewRow.Cells["colSelected"].Value)
{
quoteDetailIDs.Append(dataGridViewRow.Cells["colQuoteDetailID"].Value + ", ");
}
}
StringBuilder quoteDetailIDsNonStock = new StringBuilder();
if(SaveNonStockItems())
{
foreach (DataGridViewRow dataGridViewRow in grdNonStocks.Rows)
{
if (dataGridViewRow.Cells["colSelectedNonStock"].Value != null &&
dataGridViewRow.Cells["colSelectedNonStock"].Value != DBNull.Value &&
(bool)dataGridViewRow.Cells["colSelectedNonStock"].Value)
{
quoteDetailIDsNonStock.Append(dataGridViewRow.Cells["colQuoteDetailID2"].Value + ", ");
}
}
// Remove trailing ', '
quoteDetailIDs.Append(quoteDetailIDsNonStock.ToString());
quoteDetailIDs.Remove(quoteDetailIDs.Length - 2, 2);
Guid orderID = Guid.Empty;
try
{
BeginInit("Converting " + _quotesModule.QuoteTypeInfo.TypeName + "# " + _quotesModule.QuoteHeader[0].QuoteHeaderID + " To Order...");
_quotesModule.ConvertToOrder(_quotesModule.QuoteHeader[0].QuoteHeaderID, _quotesModule.QuoteHeader[0].CustTreeNodeID,Guid.Empty,_quotesModule.QuoteHeader[0].SupplyChainNodeID, txtPONumber.Text, quoteDetailIDs.ToString(),
chkCopyItemNotes.Checked, rdoOpenOrder.Checked ? 1 : 2,
rdoOpenOrder.Checked ? 0 : ctrlVendor.SelectedSupplyChainNodeID,
ref orderID, SessionModule.Current.User.UnityUserID);
EndInit();
Global.AppResume();
if (orderID != Guid.Empty)
{
Navigate.ReOpenOrder(orderID);
}
DialogResult = DialogResult.OK;
}
catch (Exception ex)
{
ErrorDialog.DisplayModal(ex);
EndInit();
Global.AppResume();
DialogResult = DialogResult.Cancel;
}
}
private bool SaveNonStockItems()
{
if (grdNonStocks.Rows.Count > 0)
{
foreach (DataGridViewRow dataGridViewRow in grdNonStocks.Rows)
{
if (dataGridViewRow.Cells["colSelectedNonStock"].Value != null &&
dataGridViewRow.Cells["colSelectedNonStock"].Value != DBNull.Value &&
(bool)dataGridViewRow.Cells["colSelectedNonStock"].Value)
{
string xml = CreateXml(dataGridViewRow);
if (xml != string.Empty)
{
try
{
int _skuID = ProductMaint.CreateNonStockingSku(xml, SessionModule.UserID); //Proc that inserts this
/* capture the item number for adding to the order (hack-ish) */
dataGridViewRow.Cells["colSkuID"].Value = _skuID;
}
catch (MercuryException mex)
{
/* non-stock creation failed */
ErrorDialog.DisplayModal("Non-stock creation failed.", mex.Message, true);
throw mex;
}
}
else
{
ErrorDialog.DisplayModal("Failed to generate creation parameters.");
return false;
}
}
}
}
return true;
}
private string CreateXml(DataGridViewRow dataGridViewRow)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
System.Xml.XmlNode root = doc.CreateElement("NonStockingSku");
System.Xml.XmlNode sku = doc.CreateElement("Sku");
System.Xml.XmlAttribute attr = null;
doc.AppendChild(root);
root.AppendChild(sku);
attr = doc.CreateAttribute("ItemNumber");
attr.Value = dataGridViewRow.Cells["colItemNumber2"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("Description");
attr.Value = dataGridViewRow.Cells["colItemDescription2"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("ProductTypeID");
attr.Value = dataGridViewRow.Cells["colType"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("ProductLineID");
attr.Value = dataGridViewRow.Cells["colProductLine"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("ProductDepartmentID");
attr.Value = dataGridViewRow.Cells["colDepartment"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("Landed");
attr.Value = dataGridViewRow.Cells["colLanded"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("VendorSupplyChainNodeID");
attr.Value = dataGridViewRow.Cells["colVendor"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("ListPrice");
attr.Value = dataGridViewRow.Cells["colListPrice"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("Cost");
attr.Value = dataGridViewRow.Cells["colCost"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("QuoteDetailID");
attr.Value = dataGridViewRow.Cells["colQuoteDetailID2"].Value.ToString();
sku.Attributes.Append(attr);
attr = doc.CreateAttribute("Quantity");
attr.Value = dataGridViewRow.Cells["colQuantity"].Value.ToString();
sku.Attributes.Append(attr);
return doc.OuterXml;
}
}
public static int CreateNonStockingSku(string parametersXml, int unityUserID)
{
Proc p = new Proc("NonStockingSku_i");
p["#ParametersXml"] = parametersXml;
p["#UnityUserID"] = unityUserID;
p.Exec();
int skuID;
string message;
if (p["#SkuID"] != DBNull.Value)
{
skuID = (int)p["#SkuID"];
return skuID;
}
else
{
if (p["#Message"] != DBNull.Value)
{
message = p["#Message"].ToString();
}
else
{
message = "Unspecified error.";
}
throw new MercuryException(message);
}
}
I just want to know the reson for it to behave like this. I have never encountered such problem in winforms, Is it because i am saving in loop or what i can't find problem, its a headache cuz only way is find problem is DEBUGGING however when i debug the code it works fine and results show fine.
Also, Data is getting stored in DB correctly it just does not load correctly at the form it navigates to.

Display sequence messages

I'm trying to display the messages from a sequence diagram, but so far no luck
Here's my code:
The function browse recursively calls itself to discover the diagrams, but i'm having no luck with DiagramLinks or DiagramObjects, any hint ?
private void browse(EA.Repository Repository, int ID, EA.ObjectType otype)
{
if (otype == EA.ObjectType.otPackage)
{
EA.Package pack = Repository.GetPackageByID(ID);
foreach(EA.Element el in pack.Elements)
{
ID = el.ElementID;
otype = el.ObjectType;
this.browse(Repository, ID, otype);
}
}
if (otype == EA.ObjectType.otElement)
{
EA.Element el = Repository.GetElementByID(ID);
foreach (EA.Diagram diag in el.Diagrams)
{
ID = diag.DiagramID;
otype = diag.ObjectType;
this.browse(Repository, ID, otype);
}
}
if (otype == EA.ObjectType.otDiagram)
{
EA.Diagram diag = Repository.GetDiagramByID(ID);
//foreach (EA.DiagramLink dobj in diag.DiagramLinks)
//{
MessageBox.Show(diag.Name+diag.Type);
//}
}
}
Here's the function that recognizes if the addin is launched from mainmenu, treeview or diagram.
It calls the above function Browse
private string simplify(EA.Repository Repository, string Location)
{
String s = "";
if (Location == "MainMenu") {
s = "ROOT";
MessageBox.Show("test");
}
else if (Location == "TreeView")
{
//Get the element in the tree view which was clicked
Object obj = null;
EA.ObjectType otype = Repository.GetTreeSelectedItem(out obj);
//Si le type n'arrive pas a etre determiné
if (!Enum.IsDefined(typeof(EA.ObjectType), otype))
{
//Should not occur
String error = "Type indeterminé.";
MessageBox.Show(error, "Erreur");
}
//The user clicked on a package - try to determine the stereotype
else if (otype == EA.ObjectType.otPackage)
{
EA.Package p = (EA.Package)obj;
//If the package has no superpackage, it must be the very top package
//-> if the very top package is clicked, ALL will be validated
int ID = p.PackageID;
bool hasParent = false;
try
{
int dummy = p.ParentID;
if (dummy != 0)
hasParent = true;
}
catch (Exception e) { }
if (!hasParent)
{
s = "ROOT";
}
else
{
this.browse(Repository, ID, otype);
}
}
else
{
int ID = 0;
if (otype == EA.ObjectType.otDiagram)
{
ID = ((EA.Diagram)obj).DiagramID;
EA.Diagram d = Repository.GetDiagramByID(ID);
this.browse(Repository, ID, otype);
}
else if (otype == EA.ObjectType.otElement)
{
ID = ((EA.Element)obj).ElementID;
EA.Element e = Repository.GetElementByID(ID);
this.browse(Repository, ID, otype);
}
}
if (obj == null)
s = "From Main Menu";
}
//If the users clicks into a diagram we must determine to which package
//the diagram belongs
else if (Location == "Diagram")
{
int ID = 0;
try
{
Object obj = null;
EA.ObjectType otype = Repository.GetContextItem(out obj);
if (otype == EA.ObjectType.otDiagram)
{
ID = ((EA.Diagram)obj).DiagramID;
EA.Diagram d = Repository.GetDiagramByID(ID);
this.browse(Repository, ID, otype);
}
else if (otype == EA.ObjectType.otElement)
{
ID = ((EA.Element)obj).ElementID;
EA.Element e = Repository.GetElementByID(ID);
this.browse(Repository, ID, otype);
}
else
{
Repository.Models.GetAt(0);
s = "From Main Menu";
}
}
catch (Exception ex)
{ }
}
return s;
this.encours = true;
}
The following Perl script snippet (hopefully it's readable) demonstrates what to do to get the connectors:
my $dia = $rep->GetDiagramByGUID("{7EA250AD-F37A-4e9a-9C52-BF8FCA3D87F7}"); # access the diagram
for (my $i = 0 ; $i < $dia->DiagramObjects->Count; $i++) { # every object inside the diagram
my $do = $dia->DiagramObjects->GetAt($i);
my $e = $rep->GetElementByID($do->ElementID); # the according element
next unless $e->Type eq "Sequence"; # look only at life lines
for (my $j = 0 ; $j < $e->Connectors->Count; $j++) { # now go through its connectors
my $con = $e->Connectors->GetAt($j);
print $con->Type . "\n"; # will print Sequence
}
}
Thanks a lot for your help Thomas
Here's the code i translated in C#
if (otype == EA.ObjectType.otDiagram)
{
EA.Diagram diag = Repository.GetDiagramByID(ID);
foreach (EA.DiagramObject dobj in diag.DiagramObjects)
{
EA.Element el = Repository.GetElementByID(dobj.ElementID);
foreach (EA.Connector con in el.Connectors)
{
if (con.Type == "Sequence")
{
MessageBox.Show(con.Name);
}
}
}
}

Select an option of a html page

Im trying to get my application to select an option out of a page
If looked on site for some help but could not find anything so some help would be nice
My code:
private void sellCars()
{
HtmlElementCollection elements = this.get_mainframe_tags("img");
IEnumerator enumerator2;
elements = this.get_mainframe_tags("option");
try
{
enumerator2 = elements.GetEnumerator();
while (enumerator2.MoveNext())
{
HtmlElement element2 = (HtmlElement)enumerator2.Current;
Console.WriteLine("Test = " + element2.GetAttribute("value").ToString() + "");
if (element2.GetAttribute("value").ToString() == "sell")
{
Console.WriteLine("Called");
element2.SetAttribute("value", "sell");
}
}
}
finally
{
enumerator2 = elements.GetEnumerator();
if (enumerator2 is IDisposable)
{
(enumerator2 as IDisposable).Dispose();
}
}
}

Categories

Resources