|
vkEE wrote: any ideas? Yes, this seems more appropriate to the ASP.NET forum.
Veni, vidi, abiit domum
|
|
|
|
|
Hi All,
I am facing "Out of Memory" issue when I am populating TreeView hierarchy using XML. Our XML structure is very complex and it is not in fix format. There are multiple level of child nodes. I am using recursion to iterate XML and populate TreeView structure. I tried to call GC.Collect() to clear memory but still it is throwing same error.
I am using C# of .NET framework 3.5 for development.
I will appreciate if you can help me to find solution for this.
I'm providing the Code, Which I'm using for populating the treeview, below
private void addTreeNode(XmlNode xmlNode, TreeNode treeNode)
{
string attribute = "";
treeView1.ImageList = imageList1;
treeViewResponse.ImageList = imageList1;
XmlNode xNode;
TreeNode tNode;
XmlNodeList xNodeList;
foo.MoveToFollowing(XPathNodeType.Element);
namespaces1 = foo.GetNamespacesInScope(XmlNamespaceScope.All);
if (xmlNode.HasChildNodes)
{
treeNode.ImageIndex = 0;
treeNode.SelectedImageIndex = 0;
xNodeList = xmlNode.ChildNodes;
for (int x = 0; x <= xNodeList.Count - 1; x++)
{
xNode = xmlNode.ChildNodes[x];
treeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = treeNode.Nodes[x];
//treeNode.Nodes[x].ImageIndex = -1;
addTreeNode(xNode, tNode);
}
}
else
{
treeNode.ImageIndex = 1;
treeNode.NodeFont = new Font("Arial", 8, FontStyle.Bold);
treeNode.SelectedImageIndex = 1;
treeNode.Text = xmlNode.OuterXml.Trim();
}
}
Thanks in advance.
Regards,
Rajeev
|
|
|
|
|
It's probably not a memory problem.
OutOfMemory can also be thrown if you exhaust the handle pools. How many items are in this TreeView?
The common technique to avoid spending a ton of resources and time populating a TreeView is to just populate the top-level items, putting dummy placeholder items in the folders so you get a expand button next to the folder. When the folder is expanded, remove the dummy item and repopulate that folder with its real child items, including more dummy filled folders as required.
|
|
|
|
|
Member 7680434 wrote: xmlNode.OuterXml.Trim(); You don't want to create a new large string and put that in a node; it is a new object that will consume memory.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
If you don't take the trouble to use the CP editor, and enclose your code in the right tags, and format it so it's readable, then you are discouraging people from even trying to assist you.
In addition, it's probably going to be hard to estimate the source of an out-of-memory error without knowing something about the size of your data, and the machine spec on which you are trying to create the TreeView.
Something that "jumps out at me," just glancing at your code is that you are executing code that modifies the entire TreeView inside your recursive procedure that builds it, like: treeView1.ImageList = imageList1;
Also, I don't see you actually adding a Node to the Nodes Collection of the TreeView itself in your code.
Have you verified that your code to build the TreeView works on a small XML dataset ?
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
|
|
|
|
|
Hi All,
I have a column in my table which contains a string that can have data like below:
ABC 1
ABC 10
ABC 2
ABC 100
ADBCDEF - 1
ADBCDEF - 10
ADBCDEF - 3
I need the output to be like:
ABC 1
ABC 2
ABC 10
ABC 100
ADBCDEF - 1
ADBCDEF - 3
ADBCDEF - 10
When i apply dataview.sort, it gives output as:
ABC 1
ABC 10
ABC 100
ABC 2
I need to sort my datagrid with the above column.
Can anyone provide a sorting algorithm to solve this.
Thanks
Sai
|
|
|
|
|
Tricky case.
I would split the numerical part and text part, but keep them in one class.
* Then you can order by the text first and with the numeric part second through a custom function implementing some sorting algorithm.
* or group first by text and with an array of integer attached to them like "ABC" with { 1, 2, 10, 100 } eg. Then you can order the class with the text property and print the concatenated text/integer ordered by the numerical part.
* If they can stay split in the dataview you could just do like in a database´s order by clause, simplifying things a bit.
Hope this helps.
|
|
|
|
|
It depends. In the general case, that's called Natural Sort, which isn't one specific algorithm but a family of different ways to compare strings such that their order looks "natural". That's an inherently ambiguous requirement, so there are many different implementations. It gets particularly difficult if you want to include dates.
If it's just about strings that end in some number of digits, there is an easy ad-hoc solution for that.
|
|
|
|
|
This works the way you have described. It may not be very efficient so you may want to optimise it somewhat:
public static int Compare(string first, string second)
{
if (object.ReferenceEquals(first, second))
return 0;
if (object.ReferenceEquals(null, first))
return -1;
char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8','9' };
int firstDigitIndex = first.IndexOfAny(digits);
int secondDigitIndex = second.IndexOfAny(digits);
string firstLhs = firstDigitIndex == -1 ? first : first.Substring(0, firstDigitIndex);
string secondLhs = secondDigitIndex == -1 ? second : second.Substring(0, firstDigitIndex);
int result = firstLhs.CompareTo(secondLhs);
if (result == 0)
{
int firstInteger = 0;
int secondInteger = 0;
if (firstDigitIndex > -1)
int.TryParse(first.Substring(firstDigitIndex), out firstInteger);
if (secondDigitIndex > -1)
int.TryParse(second.Substring(secondDigitIndex), out secondInteger);
result = firstInteger.CompareTo(secondInteger);
}
return result;
}
Test:
SortAndWriteList(new List<string>(new string[] { "ABC 1", "ABC 10", "ABC 2", "ABC 100" }));
Console.WriteLine();
SortAndWriteList(new List<string>(new string[] { "ADBCDEF - 1", "ADBCDEF - 10", "ADBCDEF - 3" }));
Console.WriteLine();
Console.ReadKey();
private static void SortAndWriteList(List<string> list)
{
if (list != null)
{
list.Sort(new Comparison<string>(Compare));
foreach (string item in list)
Console.WriteLine(item);
}
}
Result:
ABC 1
ABC 2
ABC 10
ABC 100
ADBCDEF - 1
ADBCDEF - 3
ADBCDEF - 10
|
|
|
|
|
If you want to duplicate the natural sort order used in Windows Explorer, the simplest option is to P/Invoke the StrCmpLogicalW function[^] from shlwapi.dll :
public class LogicalStringComparer : IComparer<string>
{
[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
private static extern int StrCmpLogicalW(string x, string y);
public int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
StrCmpLogicalW on MSDN[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
i did the serialize & de-serialize controls property this way but my way was not effective. so here is the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml;
using MetroFramework;
namespace CSRAssistant
{
class Utils
{
public static void SaveProperty(System.ComponentModel.Component _Control)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Products.xml", settings);
PropertyInfo[] properties = _Control.GetType().GetProperties();
writer.WriteStartElement("metroStyleManager");
foreach (PropertyInfo pi in properties)
{
writer.WriteElementString(pi.Name, Convert.ToString(pi.GetValue(_Control, null)));
}
writer.WriteEndDocument();
writer.Flush();
writer.Close();
}
public static void ReadProperty(System.ComponentModel.Component _Control)
{
string _property = "", _value = "";
if (System.IO.File.Exists(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Products.xml"))
{
XmlReader rdr = XmlReader.Create(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Products.xml");
while (rdr.Read())
{
if (rdr.NodeType == XmlNodeType.Element)
{
if (rdr.LocalName.ToUpper() != "METROSTYLEMANAGER")
{
_property = rdr.LocalName;
_value = rdr.ReadInnerXml();
if (_property.ToUpper() == "STYLE")
((MetroFramework.Components.MetroStyleManager)_Control).Style = (MetroColorStyle)Enum.Parse(typeof(MetroColorStyle), _value);
if (_property.ToUpper() == "THEME")
((MetroFramework.Components.MetroStyleManager)_Control).Theme = (MetroThemeStyle)Enum.Parse(typeof(MetroThemeStyle), _value);
}
}
}
rdr.Close();
}
}
}
}
if control's any property is related with enum then i had handle it different for saving and reading purpose. so please look into my code and guide with best and easy to do so as a result i can very easily save & read any controls any nested property. thanks
tbhattacharjee
|
|
|
|
|
Code posted here is from: [^].
Trying to serialize Controls ... as Controls ... in Windows Forms never works; creating a Class, or Struct, to handle serializing selected Properties, and de-serializing them, works okay.
I would guess there's a specific Metro FrameWork forum somewhere (on MSDN ?) where you could get some guidance: perhaps there's some added functionality in the MetroFrameWork for doing this ?
There is a Windows 8/RT/Metro Forum here on CP: [^], although traffic is very light.
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
|
|
|
|
|
I am not getting the difference between JavaScript var and C# dynamic, I think both works the same. Could someone tell me if there is any difference.
Thanks.
Sanju Uthaiah Bollera
|
|
|
|
|
|
First, in comparing JavaScript and C#: you are comparing "dogs" to "cats."
JavaScript is a loosely-typed language where all variables Types are determined at run-time; C# is a strongly-typed language where all variable Types must be known at compile-time.
With C# 4.0 came the implementation of the 'dynamic keyword which allows a functionality similar to JavaScript's 'var: determination of Type of a 'dynamic C# variable can be resolved at run-time. In computer science terms this is "late-binding."
So, you can do this in C#:
dynamic v1 = "string";
v1 = 100;
v1 = new Dictionary<string, string>(); That's nonsense of course, but it illustrates the fact that the compiler will not throw an error, which indicates that a 'dynamic variable in C# can be used for "anything."
In JavaScript declaring a variable with 'var makes it a local variable. In C# 'var is short-hand for "the Type is inferred from the context," and is used to save duplicating Type declarations on the left-hand side of a variable declaration, and to hold the anonymous Types resulting from Linq operations, queries, etc.
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
|
|
|
|
|
please tell me about the keyDown event that using enter key.
i have used the code, but it transfer the controll to next cell after pressing the enter key two times
|
|
|
|
|
abdul rafi wrote: but it transfer the controll to next cell after pressing the enter key two times That's the default behaviour of the datagridview (and hence, what most users will expect).
You might find this[^] interesting.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Dear Sir/Mam,
How to create the 3D type image Model.
|
|
|
|
|
You need to research the 3D graphics libraries.
Veni, vidi, abiit domum
|
|
|
|
|
Or go to Victoria's Secret and ask if you can borrow one of their angels.
|
|
|
|
|
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Applica
{
class Program
{
static void Main(string[] args)
{
long Totbyte = 0;
string filePath = null;
DirectoryInfo da = new DirectoryInfo("C:\\Folder");
FileInfo[] Arr = da.GetFiles();
foreach (FileInfo ap in Arr)
{
Totbyte = ap.Length;
filePath = ap.FullName;
}
Console.WriteLine("Total Bytes = {0} bytes", Totbyte);
string temPath = Path.GetTempFileName();
byte[] data = new byte[Totbyte];
if (File.Exists(temPath))
{
data = File.ReadAllBytes(filePath);
File.WriteAllBytes(temPath, data);
}
decimal[] arry = new decimal[Totbyte];
for (int count = 0; count < data.Length; count++)
{
arry[count] = data[count];
}
byte[] data2 = new byte[Totbyte];
for (int count = 0; count < arry.Length; count++)
{
data2[count] = (byte)arry[count];
}
FileStream file = new FileStream(filePath, FileMode.Create);
BinaryWriter binarystream = new BinaryWriter(file);
binarystream.Write(data2);
binarystream.Close();
}
}
}
|
|
|
|
|
Firstly, why have you reposted this question when Harold is already helping you on your previous copy of this question[^]?
Secondly, the code you have posted does not produce a "garbage file". The bytes in data2 will match the bytes in data exactly. You will end up overwriting the original file with an exact copy of itself.
Thirdly, you state that you don't know how to use the File.WriteAllBytes method, and yet you have a perfectly valid example of it in your code!
Cleaning up your code, replacing the BinaryWriter with File.WriteAllBytes , and adding some sanity checks:
DirectoryInfo da = new DirectoryInfo("C:\\Folder");
FileInfo[] Arr = da.GetFiles();
if (Arr.Length == 0)
{
throw new InvalidOperationException("No files found.");
}
FileInfo ap = Arr[Arr.Length - 1];
long Totbyte = ap.Length;
string filePath = ap.FullName;
Console.WriteLine("Total Bytes = {0} bytes", Totbyte);
string temPath = Path.GetTempFileName();
byte[] data = File.ReadAllBytes(filePath);
File.WriteAllBytes(temPath, data);
decimal[] arry = new decimal[Totbyte];
for (int count = 0; count < data.Length; count++)
{
arry[count] = data[count];
}
byte[] data2 = new byte[Totbyte];
for (int count = 0; count < arry.Length; count++)
{
data2[count] = (byte)arry[count];
}
if (data2.Length != data.Length)
{
throw new InvalidOperationException("Wrong length!");
}
for (int index = 0; index < data.Length; index++)
{
if (data[index] != data2[index])
{
throw new InvalidOperationException("Data has changed at index " + index);
}
}
File.WriteAllBytes(filePath, data2);
data = File.ReadAllBytes(temPath);
data2 = File.ReadAllBytes(filePath);
if (data2.Length != data.Length)
{
throw new InvalidOperationException("Wrong length!");
}
for (int index = 0; index < data.Length; index++)
{
if (data[index] != data2[index])
{
throw new InvalidOperationException("Data has changed at index " + index);
}
}
If you run this code and end up with a "garbage" file, that means you started with a garbage file!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Can you put the new file in another directory so I can have two files to compare later? Or maybe just change the name so i can have two files to compare?
|
|
|
|
|
Yes, you just need to change the path in your WriteAllBytes call:
string filePath2 = Path.Combine("C:\\A Different Folder", Path.GetFileName(filePath));
File.WriteAllBytes(filePath2, data2);
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
<pre>
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Applica
{
class Program
{
static void Main(string[] args)
{
DirectoryInfo da = new DirectoryInfo("C:\\Folder");
FileInfo[] Arr = da.GetFiles();
if (Arr.Length == 0)
{
throw new InvalidOperationException("No files found.");
}
FileInfo ap = Arr[Arr.Length - 1];
long Totbyte = ap.Length;
string filePath = ap.FullName;
Console.WriteLine("Total Bytes = {0} bytes", Totbyte);
string temPath = Path.GetTempFileName();
byte[] data = File.ReadAllBytes(filePath);
File.WriteAllBytes(temPath, data);
decimal[] arry = new decimal[Totbyte];
for (int count = 0; count < data.Length; count++)
{
arry[count] = data[count];
}
byte[] data2 = new byte[Totbyte];
for (int count = 0; count < arry.Length; count++)
{
data2[count] = (byte)arry[count];
}
if (data2.Length != data.Length)
{
throw new InvalidOperationException("Wrong length!");
}
for (int index = 0; index < data.Length; index++)
{
if (data[index] != data2[index])
{
throw new InvalidOperationException("Data has changed at index " + index);
}
}
string filePath2 = Path.Combine("C:\\check", Path.GetFileName(filePath));
File.WriteAllBytes(filePath, data2);
data = File.ReadAllBytes(temPath);
data2 = File.ReadAllBytes(filePath);
if (data2.Length != data.Length)
{
throw new InvalidOperationException("Wrong length!");
}
for (int index = 0; index < data.Length; index++)
{
if (data[index] != data2[index])
{
throw new InvalidOperationException("Data has changed at index " + index);
}
}
}
}
}
|
|
|
|
|