Retrieve checked Items in checkedListBox from text file - c#

I have a text file with one word per line which represents the checkedListBox I have checked previously. Now when the application is re-run I want the checkedListBox items to already be checked, I've tried:
System.IO.StreamReader file = new System.IO.StreamReader(#"checked.txt");
foreach (var checked in file.ReadLine())
{
lstCheckBox.SetItemChecked(checked, true);
}
This doesn't seem to work, whilst debugging the application crashes, any ideas where I'm going wrong?
Error:
InvalidArgument=Value of '97' is not valid for 'index'.
Parameter name: index
FIXED
foreach (var checked in File.ReadAllLines(#"checked.txt"))
{
int index = lstCheckBox.Items.IndexOf(checked);
if (index > 0)
{
lstCheckBox.SetItemChecked(index, true);
}
}

This is because ReadLine returns a single line, and you're iterating the characters in the line.
string line;
while ((line = file.ReadLine()) != null)
{
var index = int.Parse(line);
lstCheckBox.SetItemChecked(checked, true);
}
Should fix the problem.
Alternatively, you could use the following code instead (not using StreamReader).
foreach (var line in File.ReadAllLines("checked.txt"))
{
var index = int.Parse(line);
lstCheckBox.SetItemChecked(checked, true);
}

Related

Iterating over all hyperlinks in an excel sheet using OpenXML doesn't return all hyperlinks

I am observing a very weird behavior here. I have an excel document (.xlsx) and My goal is to edit all the hyperlinks that meet a certain criteria.
The first time I iterate, I am able to edit most of the links. There are 4 links that still remain. Then I run the program again. Now 2 remain. Then I run the program yet again, and finally all links are replaced.
Here is the snippet:
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(FilePath, true))
{
WorkbookPart wbPart = doc.WorkbookPart;
// Replace hyperlink targets
foreach (var worksheet in wbPart.WorksheetParts)
{
var hyperLinkRelations = worksheet.HyperlinkRelationships;
for (int i = 0; i < hyperLinkRelations.Count(); i++)
{
var link = hyperLinkRelations.ElementAt(i);
try
{
if (link != null && link.Uri != null && Utils.IsToBeReplaced(link.Uri.AbsoluteUri))
{
string relationId = link.Id;
string destUrl = GetReplacementUrl(link.Uri.AbsoluteUri);
if (destUrl != null)
{
worksheet.DeleteReferenceRelationship(link);
worksheet.AddHyperlinkRelationship(new Uri(destUrl, UriKind.Absolute), true, relationId);
}
}
}
catch (Exception ex)
{
Logger.Log(ex);
}
}
}
}
I have checked the utility methods "IsToBeReplaced()" and "GetReplacementUrl()" are functioning normally. I put a break point and discovered that the URLs that don't get replaced, simply do not show up in the "HyperlinkRelationships" collection.
Here is the excel file that I am working with: https://app.box.com/s/j3ulbxfafzxgcqiaep148a8yq4iy37ow
I would guess your indexing is throwing it off.
As a first attempt I would try working backwards.
ie something like:
var hcount = hyperLinkRelations.Count();
for (int i = hcount - 1; i >= 0; i--)
Otherwise, after you delete then add the relationship your i variable updates but the collection has been renumbered / shifted up by one so i will have skipped an element.

C# ConsoleRead() input not saved in variable

I am working with C# for the first time and I am facing a strange issue.
I am building my own class for a plugin, but copied parts of the code from an existing class. Basically it's
var sanInput = Console.ReadLine();
alternativeNames = sanInput.Split(',');
sanList = new List<string>(alternativeNames);
but somehow this doesn't work. The debug console says System.Console.ReadLine returned jogi,philipp string, but sanInput keeps null as its value.
Even stranger is the fact, that the next step works "a bit". string.Split returned {string[2]} string[], so it returns an array of [jogi, philipp], but still sanInput, alternativeNamesand sanList stay as null.
How is it possible, that the second line works if sanInput has no value and how can I fix this problem? When I work with the existing class with the same code everything works as expected.
//EDIT:
Looks like a quite complicated issue. Here is the complete method:
public override void HandleMenuResponse(string response, List<Target> targets)
{
if (response == "r")
{
Console.WriteLine("Which hosts do you want to configure? Enter numbers separated by a comma.");
var hostsInput = Console.ReadLine();
int[] hosts = null;
string[] alternativeNames = null;
List<string> sanList = null;
hosts = hostsInput.Split(',').Select(int.Parse).ToArray();
Console.Write("Generating certificates for ");
foreach (int entry in hosts)
{
Console.Write(targets[entry - 1].Host + ", ");
}
Console.Write("\n \n");
foreach (int entry in hosts)
{
int entry2 = entry - 1;
if (Program.Options.San)
{
Console.WriteLine("Enter all Alternative Names for " + targets[entry2].Host + " seperated by a comma:");
// Copied from http://stackoverflow.com/a/16638000
int BufferSize = 16384;
Stream inputStream = Console.OpenStandardInput(BufferSize);
Console.SetIn(new StreamReader(inputStream, Console.InputEncoding, false, BufferSize));
var sanInput = Console.ReadLine();
alternativeNames = sanInput.Split(',');
sanList = new List<string>(alternativeNames);
targets[entry2].AlternativeNames.AddRange(sanList);
}
Auto(targets[entry - 1]);
}
}
if (response == "e")
{
string[] alternativeNames = null;
List<string> sanList = new List<string>();
if (Program.Options.San)
{
Console.WriteLine("Enter all Alternative Names seperated by a comma:");
// Copied from http://stackoverflow.com/a/16638000
int BufferSize = 16384;
Stream inputStream = Console.OpenStandardInput(BufferSize);
Console.SetIn(new StreamReader(inputStream, Console.InputEncoding, false, BufferSize));
var sanInput = Console.ReadLine();
alternativeNames = sanInput.Split(',');
}
if (alternativeNames != null)
{
sanList = new List<string>(alternativeNames);
}
foreach (var entry in targets)
{
Auto(entry);
}
}
}
I know the code isn't pretty and efficient. All in all it let's the user decide if he wants to use all detected hosts (response e) or only single ones (response r). But the mentioned problem occurs only in the second if-method. If I switch them it's again the latter one. So maybe the reason lies in the main program or in this BufferSize-Stuff? I don't know.
//EDIT 2: I think I found the problem: Somehow the integer BufferSize (shortly before the Console.Read()) is set to 0, so of course without any buffer it can't read the input. So the question remains: Why?
//EDIT 3: Okay, I'm done. It looks like I can't use the same name for the variables although they are in two different if-methods. I just named them sanInput2, alternativeNames2 etc. and now everything works.
try this, all of the variables are having values(you can use var also for all the variables):
var sanInput = Console.ReadLine();
string[] alternativeNames = sanInput.Split(',');
List<string> sanList = new List<string>(alternativeNames);
The problem you mention is, that debugging code in VS do assignements in two steps. First is to execute Console.ReadLine() (therefore you see Console.Readline returned message) and AFTER that is is assigned into sanInput. Same situation is after Split. Function is called, but not assigned yet.
My recommendation: use rather the step over instead of step inside. After time, you get used to this functionality and appreciate it.

C# treeview from dot notation flat file

I have a flat file that looks like this:
.root:NODE
.root.branch1:NODE
.root.branch1.size:INT
.root.branch1.name:STRING
.root.branch2:NODE
.root.branch2.flavor:NODE
.root.branch2.flavor.cost:INT
.root.branch2.flavor.name:STRING
The file contents, depth, lenght, etc., will be different every time, so I can't hardcode anything (though the nodes will always be of datatype 'NODE'). I need to bring it into C# as a data source. I'm not sure what the best way to parse the file is to convert it to a structure that looks like
+root
+branch1
size:
name:
+branch2
+flavor
cost:
name:
etc. Ideally, I'd like to dynamically build a treeview control that the user can use to select the node he'd like to access (these tags are paths to an actual datasource; so elsewhere in the code, I'm using)
int iVal = somefunction.readvar(".root.branch2.flavor.cost");
/edit/ if it helps, the file I'm trying to parse is a *.SYM file (a symbols file) generated by a TwinCat 2 program. There's a little documentation here: http://infosys.beckhoff.com/content/1033/tcplccontrol/html/tcplcctrl_componentsoptions.htm#Symbol%20configuration
C# :
private void AddToTreeView()
{
TreeViewItem root = new TreeViewItem();
foreach (string line in ReadLines())
{
var parts = line.Split(new char[] { '.' },StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 1)
{
root.Header = parts[0].Split(':')[0];
root.Tag = line;
}
else
{
TreeViewItem node = root;
foreach (var part in parts)
{
var header = part.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0];
if(!IfExists(node, header, ref node))
{
node.Items.Add(new TreeViewItem()
{
Header = header,
Tag = line
});
node = root;
}
}
}
}
treeView.Items.Add(root);
}
private bool IfExists(TreeViewItem itm, string header, ref TreeViewItem which)
{
if (itm.Header as string == header)
{
which = itm;
return true;
}
foreach (TreeViewItem i in itm.Items)
{
if (i.Header as string == header)
{
which = i;
return true;
}
else if (i.HasItems)
{
if (IfExists(i, header, ref which))
return true;
}
}
return false;
}
XAML:
<TreeView x:Name="treeView" Height="100">
</TreeView>
Screenshot:
Well, this code works but, it may have some flaws and it is not a perfect solution. Anyway, even it doesn't work perfectly, it should help you in some ways.
EDİT:
This way, it sometimes doesn't work, e.g. if the nodes isn't ordered.
I changed this part of the program so it should have no other errors anymore.
if (!IfExists(node, header, ref node))
{
var currNode = new TreeViewItem()
{
Header = header,
Tag = line
};
node.Items.Add(currNode);
if (part.Contains(":"))
node = root;
else
node = currNode;
}
The previous code's output if input is:
.root:NODE
.root.branch1:NODE
.root.branch2.flavor.name:STRING
.root.branch1.size:INT
.root.branch1.name:STRING
.root.branch2:NODE
.root.branch2.flavor:NODE
.root.branch2.flavor.cost:INT
But with the changed code, it gives output exactly as it should!

Powerpoint to Text C# - Microsoft.Interop

I have been trying to read .ppt files from last 3 days. I searched a lot on internet and I came up with different source code snippets but nothing was perfect. And now i tried this code, and it is not printing "Check4" because of some unidentified problem in "Foreach" statement, and throwing an exception. Please guide me. I need it badly.
public static void ppt2txt (String source)
{
string fileName = System.IO.Path.GetFileNameWithoutExtension(source);
string filePath = System.IO.Path.GetDirectoryName(source);
Console.Write("Check1");
Application pa = new Microsoft.Office.Interop.PowerPoint.ApplicationClass ();
Microsoft.Office.Interop.PowerPoint.Presentation pp = pa.Presentations.Open (source,
Microsoft.Office.Core.MsoTriState.msoTrue,
Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoFalse);
Console.Write("Check2");
String pps = "";
Console.Write("Check3");
foreach (Microsoft.Office.Interop.PowerPoint.Slide slide in pp.Slides)
{
foreach (Microsoft.Office.Interop.PowerPoint.Shape shape in slide.Shapes)
pps += shape.TextFrame.TextRange.Text.ToString ();
}
Console.Write("Check4");
Console.WriteLine(pps);
}
Thrown exception is
System.ArgumentException: The specified value is out of range.
at Microsoft.Office.Interop.PowerPoint.TextFrame.get_TextRange()
at KareneParser.Program.ppt2txt(String source) in c:\Users\Shahmeer\Desktop\New folder (2)\KareneParser\Program.cs:line 323
at KareneParser.Program.Main(String[] args) in c:\Users\Shahmeer\Desktop\New folder (2)\KareneParser\Program.cs:line 150
Line 323 on which exception is caught
pps += shape.TextFrame.TextRange.Text.ToString ();
Thanks in advance.
It looks like you need to check your shape objects to see if they have a TextFrame and Text present.
In your nested foreach loop try this:
foreach (Microsoft.Office.Interop.PowerPoint.Slide slide in pp.Slides)
{
foreach (Microsoft.Office.Interop.PowerPoint.Shape shape in slide.Shapes)
{
if(shape.HasTextFrame == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textFrame = shape.TextFrame;
if(textFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textRange = textFrame.TextRange;
pps += textRange.Text.ToString ();
}
}
}
}
This is of course untested on my part, it looks to me though that as your foreach loops, you're trying to access some shapes in the powerpoint doc that don't have text present, hence the out of range exception. I've added in checking to make sure it only appends text to your pps string if it has Text present.
Not all shapes have text. Lines etc are also shapes.
Check for HasText first:
foreach (Microsoft.Office.Interop.PowerPoint.Shape shape in slide.Shapes)
{
if(shape.TextFrame.HasText)
{
pps += shape.TextFrame.TextRange.Text;
}
}

C# listview searching virtual mode

i'm having trouble searching a virtual listview in c#.
what i am doing right now is reading a large log file. here is what i have implemented so far
I read the file one line at a time and note the position of the start of the line. Add these positions to a List and when RetrieveVirtualItem is called - look up the position in the file using the index of the item and the List and then read the line from file.
So there is no lag when reading the file.
I want to now search for items. Here is what I have thought of so far, but I have not been able to implement it successfully.
I am not actually searching the listview, but during my filereading, i mark the position of hits of the specific string, say "INFO". if it hits, i add the position to a List.
When RetrieveVirtualItem is called, I just read the line back with all the hits.
Seems that through debugging - if (line.IndexOf("INFO", StringComparison.OrdinalIgnoreCase) >= 0) is not hitting any matches. I'm not sure why, anyone help?
using (var sr = new myStreamReader("test.log"))
{
while ((line = sr.ReadLine()) != null)
{
if (line.IndexOf("INFO", StringComparison.OrdinalIgnoreCase) >= 0)
{
position = sr.BytesRead;
Search.Add(position);
searchcount++;
}
}
newMessageView.VirtualListSize = searchcount;
}
I don't know how your "myScreamReader" class works, but if it similar to StreamReader this code could be working for you:
using (var sr = new StreamReader("test.log"))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (line.IndexOf("INFO", StringComparison.OrdinalIgnoreCase) >= 0)
{
// line contains "info"
}
}
}
You should debug your code by setting a breakpoint at line.IndexOf... check to see if value of line is changing and look correct.

Categories