I post the complete code below, so you can see what I'm doing.
Situation:
I create a IHTMLDocument2 currentDoc pointing to the DomDocument
I write the proper string
I close the currentDoc
program shows me the html code including the CSS stuff 100% correct. Works
Now I want to change the CSS, instead of 2 columns I set it to 3 columns
(Simply change the width:48% to width:33%)
and rerun the code with the new 33%
now it suddenly doesn't apply any CSS style anymore.
When I close the program, and then change the CSS to 33% again, it works flawless
So, somehow, without disposing the complete webbrowser, I can't load the CSS a 2nd time..
or, the first CSS is somewhere in some cache, and conflicts with the 2nd CSS.. Just riddling here.. really need help on how to solve this
I searched the internet and stackoverflow long enough that I need to post this, even if someone else on this planet already posted it somewhere, I didn't find it.
private void doWebBrowserPreview()
{
if (lMediaFiles.Count == 0)
{
return;
}
Int32 iIndex = 0;
for (iIndex = 0; iIndex < lMediaFiles.Count; iIndex++)
{
if (!lMediaFiles[iIndex].isCorrupt())
{
break;
}
}
String strPreview = String.Empty;
String strLine = String.Empty;
// Set example Media
String strLinkHTM = lMediaFiles[iIndex].getFilePath();
FileInfo movFile = new FileInfo(strLinkHTM + lMediaFiles[iIndex].getFileMOV());
String str_sizeMB = (movFile.Length / 1048576).ToString();
if (str_sizeMB.Length > 3)
{
str_sizeMB.Insert(str_sizeMB.Length - 3, ".");
}
//Get info about our media files
MediaInfo MI = new MediaInfo();
MI.Open(strLinkHTM + lMediaFiles[iIndex].getFileM4V());
String str_m4vDuration = // MI.Get(0, 0, 80);
MI.Get(StreamKind.Video, 0, 74);
str_m4vDuration = "Duration: " + str_m4vDuration.Substring(0, 8) + " - Hours:Minutes:Seconds";
String str_m4vHeightPixel = MI.Get(StreamKind.Video, 0, "Height"); // "Height (Pixel): " +
Int32 i_32m4vHeightPixel;
Int32.TryParse(str_m4vHeightPixel, out i_32m4vHeightPixel);
i_32m4vHeightPixel += 16; // for the quicktime embed menu
str_m4vHeightPixel = i_32m4vHeightPixel.ToString();
String str_m4vWidthPixel = MI.Get(StreamKind.Video, 0, "Width"); //"Width (Pixel): " +
foreach (XElement xmlLine in s.getTemplates().getMovieHTM().Element("files").Elements("file"))
{
var query = xmlLine.Attributes("type");
foreach (XAttribute result in query)
{
if (result.Value == "htm_header")
{
foreach (XElement xmlLineDes in xmlLine.Descendants())
{
if (xmlLineDes.Name == "dataline")
{
strLine = xmlLineDes.Value;
strLine = strLine.Replace(#"%date%", lMediaFiles[iIndex].getDay().ToString() + " " + lMediaFiles[iIndex].getMonth(lMediaFiles[iIndex].getMonth()) + " " + lMediaFiles[iIndex].getYear().ToString());
strPreview += strLine + "\n";
}
}
}
}
}
strLine = "<style type=\"text/css\">" + "\n";
foreach (XElement xmlLine in s.getTemplates().getLayoutCSS().Element("layoutCSS").Elements("layout"))
{
var query = xmlLine.Attributes("type");
foreach (XAttribute result in query)
{
if (result.Value == "layoutMedia")
{
foreach (XElement xmlLineDes in xmlLine.Elements("layout"))
{
var queryL = xmlLineDes.Attributes("type");
foreach (XAttribute resultL in queryL)
{
if (resultL.Value == "layoutVideoBox")
{
foreach (XElement xmlLineDesL in xmlLineDes.Descendants())
{
if (xmlLineDesL.Name == "dataline")
{
strLine += xmlLineDesL.Value + "\n";
}
}
}
}
}
}
}
}
strLine += "</style>" + "\n";
strPreview = strPreview.Insert(strPreview.LastIndexOf("</head>", StringComparison.Ordinal), strLine);
for (Int16 i16Loop = 0; i16Loop < 3; i16Loop++)
{
foreach (XElement xmlLine in s.getTemplates().getMovieHTM().Element("files").Elements("file"))
{
var query = xmlLine.Attributes("type");
foreach (XAttribute result in query)
{
if (result.Value == "htm_videolist")
{
foreach (XElement xmlLineDes in xmlLine.Descendants())
{
if (xmlLineDes.Name == "dataline")
{
strLine = xmlLineDes.Value;
strLine = strLine.Replace(#"%m4vfile%", strLinkHTM + lMediaFiles[iIndex].getFileM4V());
strLine = strLine.Replace(#"%moviefile%", strLinkHTM + lMediaFiles[iIndex].getFileMOV());
strLine = strLine.Replace(#"%height%", str_m4vHeightPixel);
strLine = strLine.Replace(#"%width%", str_m4vWidthPixel);
strLine = strLine.Replace(#"%duration%", str_m4vDuration);
strLine = strLine.Replace(#"%sizeMB%", str_sizeMB);
strLine = strLine.Replace(#"%date%", lMediaFiles[iIndex].getDay().ToString() + " " + lMediaFiles[iIndex].getMonth(lMediaFiles[iIndex].getMonth()) + " " + lMediaFiles[iIndex].getYear().ToString());
strPreview += strLine + "\n";
}
}
}
}
}
}
foreach (XElement xmlLine in s.getTemplates().getMovieHTM().Element("files").Elements("file"))
{
var query = xmlLine.Attributes("type");
foreach (XAttribute result in query)
{
if (result.Value == "htm_footer")
{
foreach (XElement xmlLineDes in xmlLine.Descendants())
{
if (xmlLineDes.Name == "dataline")
{
strPreview += xmlLineDes.Value + "\n";
}
}
}
}
}
webBrowserPreview.Navigate("about:blank");
webBrowserPreview.Document.OpenNew(false);
mshtml.IHTMLDocument2 currentDoc = (mshtml.IHTMLDocument2)webBrowserPreview.Document.DomDocument;
currentDoc.clear();
currentDoc.write(strPreview);
currentDoc.close();
/*
try
{
if (webBrowserPreview.Document != null)
{
IHTMLDocument2 currentDocument = (IHTMLDocument2)webBrowserPreview.Document.DomDocument;
int length = currentDocument.styleSheets.length;
IHTMLStyleSheet styleSheet = currentDocument.createStyleSheet(#"", 0);
//length = currentDocument.styleSheets.length;
//styleSheet.addRule("body", "background-color:blue");
strLine = String.Empty;
foreach (XElement xmlLine in s.getTemplates().getLayoutCSS().Element("layoutCSS").Elements("layout"))
{
var query = xmlLine.Attributes("type");
foreach (XAttribute result in query)
{
if (result.Value == "layoutMedia")
{
foreach (XElement xmlLineDes in xmlLine.Elements("layout"))
{
var queryL = xmlLineDes.Attributes("type");
foreach (XAttribute resultL in queryL)
{
if (resultL.Value == "layoutVideoBox")
{
foreach (XElement xmlLineDesL in xmlLineDes.Descendants())
{
if (xmlLineDesL.Name == "dataline")
{
strLine += xmlLineDesL.Value;
}
}
}
}
}
}
}
}
//TextReader reader = new StreamReader(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "basic.css"));
//string style = reader.ReadToEnd();
styleSheet.cssText = strLine;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}*/
webBrowserPreview.Refresh();
}
I now successfully implemented the berkelium-sharp method to my project
Has the same bug!
Found a solution!
First attempt which didn't work:
I had a persistent form (main form) and inside it a nested WebBrowser.
After changing the html with it's css, i told it to navigate to this new html!
This didn't work either:
Then I tried putting webbrowser on an own form. Which I simply open/close each
time I need a refresh. TO be sure the garbage collector cleans everything
Then I tried the Berkelium and rewrote it to my needs:
same logic as attempt 2 with the webbrowser. No luck either.
So I tried to open firefox itself and see if I can emulate this behaviour with a real browser. Indeed! When I open firefox, and force open the file (if you simply open a new file, firefox doesn't actually navigate to it, but detects this was already opened and simply refreshes it)
I noticed this due to the fast opening of the page!
A little scripting to force opening the same file twice (navigating) in 1 firefox session had the same effect: all CSS corrupt!
so, for some reason, you shouldn't navigate the same file twice, but instead of closing anything, simply force a refresh! Not a "Navigate"
Hope this info can help others, since I lost a lot of time finding out that it is the "navigate" to the same file more then once causing the corruption of stylesheets
Related
I got a compiled dll and I need to run every TestCase from this dll seperately with the nunit console tool, one test after the other. To run a TestCase I need to read the name and the parameters of the TestCase from the dll.
I tried reflection, but so far I ran into several problems. Is there a simple way to get the whole TestCase to run it with the nunit console? I heard of the --explore option of nunit3 to get all information of a dll, but unfortunately I have to use the version 2.5.10.
First of all I do not get the amount of methods defined when I try this:
List<MethodInfo> testMethods = new List<MethodInfo>(from type in
assembly.GetTypes()
from method in type.GetMethods()
where method.IsDefined(typeof(TestAttribute)) ||
method.IsDefined(typeof(TestCaseAttribute))
select method);
Afterwards I iterate over the items of the list and try to get the corresponding parameters with "CustomAttributeData.GetCustomAttributes(method)". But every TestCase has a different signature, so its difficult building the form nunit-console wants, like so: methodname(param1,...,paramN)
foreach (CustomAttributeData cad in attributes)
{
String test = method.Name + "(";
String attr = String.Empty;
foreach (CustomAttributeTypedArgument cata in cad.ConstructorArguments)
{
if (cata.Value.GetType() == typeof(ReadOnlyCollection<CustomAttributeTypedArgument>))
{
foreach (CustomAttributeTypedArgument cataElement in
(ReadOnlyCollection<CustomAttributeTypedArgument>)cata.Value)
{
if (cataElement.ArgumentType.Name == "String")
{
String elem = String.Empty;
if (cataElement.Value == null)
{
attr += "null" + ",";
}
else
{
elem = cataElement.Value.ToString().Replace(#"\", #"\\");
//escape quotation marks
attr += #"\" + "\"" + elem + #"\" + "\"" + ",";
}
}
else if (cataElement.ArgumentType.IsEnum)
{
var enumName = cataElement.ArgumentType.Name;
foreach (var fieldInfo in cataElement.ArgumentType.GetFields())
{
if (fieldInfo.FieldType.IsEnum)
{
var fName = fieldInfo.Name;
var fValue = fieldInfo.GetRawConstantValue();
if (cataElement.Value.ToString().Equals(fValue.ToString()))
{
attr += fName + ",";
}
}
}
}
else
{
attr += cataElement.Value + ",";
}
}
}
else if (cata.ArgumentType.IsEnum)
{
var enumName = cata.ArgumentType.Name;
foreach (var fieldInfo in cata.ArgumentType.GetFields())
{
if (fieldInfo.FieldType.IsEnum)
{
var fName = fieldInfo.Name;
var fValue = fieldInfo.GetRawConstantValue();
if (cata.Value.ToString().Equals(fValue.ToString()))
{
attr = fName;
}
}
}
}
else if (cata.Value.GetType() == typeof(String))
{
String elem = String.Empty;
if (cata.Value == null)
{
attr = "null";
}
else
{
elem = cata.Value.ToString().Replace(#"\", #"\\");
attr = #"\" + "\"" + elem + #"\" + "\"";
}
}
else
{
attr = cata.ToString();
}
//do stuff to get form of TestCase
Indeed it needs to be refactored, but I wonder if there is an easier way to get all TestCases and its Parameters.
I have a TreeView which I need to populate dynamically.
The contents would be similar to directory structure (Refer attached pic).
Now, in order to fetch these 'folders' I use a command, which would list out only 'top-level' folders (refer pic). (Please note this is not OS directory / folders.. I am only just using directory / folder analogy to make things understandable)
So, for e.g. I have Root, Folder1, Sub_Folder1, Sub_Folder2, Sub-sub_folder_1, Folder2, then issuing command with a '/' option will give me a list: Folder1, Folder2.
If I need Level-2 folders (Sub_Folder_1 and Sub_Folder_2), I again need to issue the command with option "/Folder1"..
I need to repeatedly issue these commands, until I get the last sub.. folder and use the list to populate a TreeView.
I am using the below C# (4.5) code, but I am able to list only 2-levels.
Any help in correcting would be much appreciated!
try
{
BuildInfaCmd(InfaCmdType.ListFolders, folder);
InfaCmd icmd = CallInfaCmd(InfaCmdExe, InfaCmdArgs);
if (icmd.ExitCode() == 0)
{
List<string> folders = icmd.GetFolders();
if (folders.Count > 0)
topFolderFound = true;
foreach (string f in folders)
{
if (node == null) // Add to 'root' of Treeview
{
TreeNode p = new TreeNode(f);
treeView1.Nodes.Add(p);
PopulateFoldersRecursive(f, null);
}
else
{
callLvl += 1;
//MessageBox.Show("Calling recursive " + callLvl.ToString());
TreeNode p = new TreeNode(f);
node.Nodes.Add(p); // Add to calling node as children
string fold = node.Text + "/" + f; // The sub-folder to be provided to ListFolder command like -p /RootFolder/SubFolder1/SubFolder2/...
PopulateFoldersRecursive(fold, p, callLvl);
}
}
}
else
{
MessageBox.Show(icmd.GetError(), "Error while executing InfaCmd", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
The answers provided were more specific to populating 'Files' / 'Directories'. As conveyed, the 'folders' in my query was not OS-specific, so the answers did not provide much help. I found out a way to recursively add nodes to Treeview.
void PopulateFolders()
{
int callLvl = 1;
BuildInfaCmd(InfaCmdType.ListFolders);
int timeout = 60000;
if (lstProjects.SelectedItem.ToString().ToLower().StartsWith("hdp"))
timeout = 600000;
InfaCmd icmd = CallInfaCmd(InfaCmdExe, InfaCmdArgs,null,timeout);
if (icmd.ExitCode() == 0)
{
List<string> folders = icmd.GetFolders();
foreach (string f in folders)
{
TreeNode p = new TreeNode(f);
treeView1.Nodes.Add(p);
PopulateFoldersRecursive(f, p, 1);
}
lstFolders.DataSource = folders;
}
else
{
MessageBox.Show(icmd.GetError(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
void PopulateFoldersRecursive(string folder, TreeNode node, [Optional]int callLevel)
{
int timeout = 60000;
if (lstProjects.SelectedItem.ToString().ToLower().StartsWith("hdp"))
timeout = 600000;
int callLvl = callLevel;
string fold = "";
try
{
BuildInfaCmd(InfaCmdType.ListFolders, folder);
InfaCmd icmd = CallInfaCmd(InfaCmdExe, InfaCmdArgs,null, timeout);
if (icmd.ExitCode() == 0)
{
List<string> folders = icmd.GetFolders();
if (folders.Count > 0)
topFolderFound = true;
foreach (string f in folders)
{
callLvl += 1;
//MessageBox.Show("Calling recursive " + callLvl.ToString());
TreeNode p = new TreeNode(f);
node.Nodes.Add(p); // Add to calling node as children
// MessageBox.Show(callLvl.ToString() + "; Node.text : " + node.Text + " ; f : " + f);
dirTree.Add(p.FullPath);
if (String.IsNullOrEmpty(folderFullPath))
{
//fold = node.Text + "/" + f; // The sub-folder to be provided to ListFolder command like -p /RootFolder/SubFolder1/SubFolder2/...
fold = folder + "/" + f; // ORIGINAL
folderFullPath = fold;
}
else
{
fold = folder + "/" + f; // TEST
folderFullPath = fold; // ORIGINAL
}
PopulateFoldersRecursive(fold, p, callLvl);
}
}
}
else
{
MessageBox.Show(icmd.GetError(), "Error while executing InfaCmd", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.InnerException, "Error");
}
}
I have a small Console app where I search for keywords in a large group of .cs files. I now want to follow the inheritance of a subfile to its parent root file. So far I have completed this by using a very noobish method that I don't like.
I think Reflection will be perfect but then I struggle to figure out how to use Reflection on an external file.
Can someone advise me on how I can achieve this?
EDIT:
static string GetParent(string location, string word)
{
string[] file = location.Split(new[] { "\\" }, StringSplitOptions.None);
try
{
using (StreamReader test = new StreamReader(location))
{
while ((line = test.ReadLine()) != null)
{
if (word == "ControlEventStates" && line.Contains(file.Last().ToString().Replace(".cs", "")))
{
string[] a = line.Split(new[] { " ", "(", ")", ";", ".", ",", "<", ">" }, StringSplitOptions.None);
for (int p = 0; p < a.Length; p++)
{
if (a[p] == ":" && a[p + 1] != "FunctionBase")
{
recValue = a[p + 1] + ".cs";
foreach (var item in Frontendfiles)
{
//newlocation = item;
string loc = Path.GetFileName(item);
if (loc == recValue)
{
GetParent(item, word);
}
else if (loc != recValue)
{
FindLine(item, a[p + 1] + " : ");
}
}
}
}
if (location != "" && location != null)
{
//LinesList = FindLine(newlocation, word);
return line;
}
}
}
}
return "";
}
catch (Exception ex)
{
throw ex;
}
}
So as I said this is terrible coding for what I want to accomplish. Basically I search for the line containing the current class name then filtering out the strings to find where the parent file is. Then I use the parent file name to search for its directory and then start the process over again.
I am looking for the best way to compare XML data with a string.
the data is stored in a xml called test.xml, and must be compared with the name descendant, if there is a match more info from the xml must be added to a textbox and picture box.
My ( working ) code:
var xmlDocument = XDocument.Load("test.xml"); // XML koppellen
var key1 = xmlDocument.Descendants("NAME"); // XML filepath
var key2 = xmlDocument.Descendants("TITLE"); // XML titel
var key3 = xmlDocument.Descendants("BRAND"); // XML afbeelding
var key4 = xmlDocument.Descendants("TYPE"); // XML merk
var key5 = xmlDocument.Descendants("SOORT"); // XML type
var key6 = xmlDocument.Descendants("NAAM"); // XML naam
List<string> file = new List<string>();
List<string> title = new List<string>();
List<string> brand = new List<string>();
List<string> type = new List<string>();
List<string> soort = new List<string>();
List<string> naam = new List<string>();
int i = 0;
foreach (var key in key1)
{
file.Add(key.Value.Trim());
}
foreach (var key in key2)
{
title.Add(key.Value.Trim());
}
foreach (var key in key3)
{
brand.Add(key.Value.Trim());
}
foreach (var key in key4)
{
type.Add(key.Value.Trim());
}
foreach (var key in key5)
{
soort.Add(key.Value.Trim());
}
foreach (var key in key6)
{
naam.Add(key.Value.Trim());
}
foreach (var Name in naam)
{
if (textBox3.Text.ToString() == Name.ToString())
{
PDFLocation = file[i].ToString();
pictureBox1.Image = pdfhandler.GetPDFthumbNail(PDFLocation);
textBox4.Text =
title[i].ToString() + "\r\n" +
brand[i].ToString() + "\r\n" +
type[i].ToString() + "\r\n" +
soort[i].ToString() + "\r\n" +
textBox3.Text + "\r\n";
}
i++;
}
]
I think this is not the best way to do it, but cant see a better way....
Update: solution:
foreach (XElement element in xmlDocument.Descendants("PDFDATA"))
{
if (textBox3.Text.ToString() == element.Element("NAAM").Value.Trim())
{
PDFLocation = element.Element("NAME").Value.ToString();
pictureBox1.Image = pdfhandler.GetPDFthumbNail(PDFLocation);
textBox4.Text =
element.Element("TITLE").Value + "\r\n" +
element.Element("BRAND").Value + "\r\n";
break;
}
}
Instead of thinking of the xml and a bunch of individual lists of data, it helps to think of it more as objects. Then you can loop through each element one at a time and don't need to split it up into individual lists. This not only removes duplicate code but more importantly creates a better abstraction of the data you are working with. This makes it easier to read and understand what the code is doing.
foreach (XElement element in xmlDocument.Elements())
{
if (textBox3.Text.ToString() == element.Element("NAAM").Value)
{
PDFLocation = element.Element("NAAM").Value;
pictureBox1.Image = pdfhandler.GetPDFthumbNail(PDFLocation);
textBox4.Text =
element.Element("Title").Value + "\r\n" +
element.Element("Brand").Value + "\r\n" +
element.Element("Type").Value + "\r\n"
// access rest of properties...
}
}
Currently I am building an agenda with extra options.
for testing purposes I store the data in a simple .txt file
(after that it will be connected to the agenda of a virtual assistant.)
To change or delete text from this .txt file I have a problem.
Although the part of the content that needs to be replaced and the search string are exactly the same it doesn't replace the text in content.
code:
Change method
public override void Change(List<object> oldData, List<object> newData)
{
int index = -1;
for (int i = 0; i < agenda.Count; i++)
{
if(agenda[i].GetType() == "Task")
{
Task t = (Task)agenda[i];
if(t.remarks == oldData[0].ToString() && t.datetime == (DateTime)oldData[1] && t.reminders == oldData[2])
{
index = i;
break;
}
}
}
string search = "Task\r\nTo do: " + oldData[0].ToString() + "\r\nDateTime: " + (DateTime)oldData[1] + "\r\n";
reminders = (Dictionary<DateTime, bool>) oldData[2];
if(reminders.Count != 0)
{
search += "Reminders\r\n";
foreach (KeyValuePair<DateTime, bool> rem in reminders)
{
if (rem.Value)
search += "speak " + rem.Key + "\r\n";
else
search += rem.Key + "\r\n";
}
}
// get new data
string newRemarks = (string)newData[0];
DateTime newDateTime = (DateTime)newData[1];
Dictionary<DateTime, bool> newReminders = (Dictionary<DateTime, bool>)newData[2];
string replace = "Task\r\nTo do: " + newRemarks + "\r\nDateTime: " + newDateTime + "\r\n";
if(newReminders.Count != 0)
{
replace += "Reminders\r\n";
foreach (KeyValuePair<DateTime, bool> rem in newReminders)
{
if (rem.Value)
replace += "speak " + rem.Key + "\r\n";
else
replace += rem.Key + "\r\n";
}
}
Replace(search, replace);
if (index != -1)
{
remarks = newRemarks;
datetime = newDateTime;
reminders = newReminders;
agenda[index] = this;
}
}
replace method
private void Replace(string search, string replace)
{
StreamReader reader = new StreamReader(path);
string content = reader.ReadToEnd();
reader.Close();
content = Regex.Replace(content, search, replace);
content.Trim();
StreamWriter writer = new StreamWriter(path);
writer.Write(content);
writer.Close();
}
When running in debug I get the correct info:
content "-- agenda --\r\n\r\nTask\r\nTo do: test\r\nDateTime: 16-4-2012 15:00:00\r\nReminders:\r\nspeak 16-4-2012 13:00:00\r\n16-4-2012 13:30:00\r\n\r\nTask\r\nTo do: testing\r\nDateTime: 16-4-2012 9:00:00\r\nReminders:\r\nspeak 16-4-2012 8:00:00\r\n\r\nTask\r\nTo do: aaargh\r\nDateTime: 18-4-2012 12:00:00\r\nReminders:\r\n18-4-2012 11:00:00\r\n" string
search "Task\r\nTo do: aaargh\r\nDateTime: 18-4-2012 12:00:00\r\nReminders\r\n18-4-2012 11:00:00\r\n" string
replace "Task\r\nTo do: aaargh\r\nDateTime: 18-4-2012 13:00:00\r\nReminders\r\n18-4-2012 11:00:00\r\n" string
But it doesn't change the text. How do I make sure that the Regex.Replace finds the right piece of content?
PS. I did check several topics on this, but none of the solutions mentioned there work for me.
You missed a : right after Reminders. Just check it again :)
You could try using a StringBuilder to build up you want to write out to the file.
Just knocked up a quick example in a console app but this appears to work for me and I think it might be what you are looking for.
StringBuilder sb = new StringBuilder();
sb.Append("Tasks\r\n");
sb.Append("\r\n");
sb.Append("\tTask 1 details");
Console.WriteLine(sb.ToString());
StreamWriter writer = new StreamWriter("Tasks.txt");
writer.Write(sb.ToString());
writer.Close();