scrollbar initializes DragMove() in WPF - c#

i built a weather app that gets the weather for major cities in the world. i used wsdl to download the weather data in xml and then i get the desired data from the elements by using XmlDocument class. i display this information in a textbox. i set the HorizontalScrollBarVisibility & VerticalScrollBarVisibility of the textbox to auto so it displays a scrollbar should the text be too long. i have also implemented a _MouseLeftButtonDown listener because i have removed the title bar from my app. however everytime the scrollbar is displayed and i click it, the DragMove() method is called and thus i cannot scroll through the text.
how can i prevent this from happening?
here's my code, it only works with the GlobalWeather and Countries classes i converted from wsdl. if you want i can post the code or you can download the wsdl of these classes and convert it to .cs...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
namespace WeatherApp
{
/// <summary>
/// Interaktionslogik für Window1.xaml
/// </summary>
public partial class Window1 : Window
{
// http://www.webservicex.net/globalweather.asmx?WSDL
private static GlobalWeather wetterObjekt;
//http://www.webservicex.net/ws/WSDetails.aspx?WSID=17&CATID=7
Country country;
private static string wetter;
private static string wetterAktuell;
private static List<string> countryList;
private static List<string> cityList;
public Window1 ()
{
InitializeComponent ();
wetterAktuell = "";
wetter = "";
wetterObjekt = new GlobalWeather ();
country = new Country ();
countryList = new List<string> ();
cityList = new List<string> ();
getCountries ();
string firstStr = "(keins ausgewählt)";
object firstItem = firstStr;
txtStadt.Items.Add(firstItem);
txtStadt.SelectedIndex = 0;
txtLand.SelectedIndex = 0;
txtWetter.IsEnabled = false;
txtLand.SelectionChanged += new SelectionChangedEventHandler ( txtLand_SelectionChanged );
}
private void txtLand_SelectionChanged ( object sender, SelectionChangedEventArgs e )
{
Console.WriteLine(cityList.Count);
if (cityList.Count > 0)
{
txtStadt.Items.Clear();
cityList.Clear();
string firstStr = "(keins ausgewählt)";
object firstItem = firstStr;
txtStadt.Items.Add(firstItem);
txtStadt.SelectedIndex = 0;
}
if ((string)(txtLand.SelectedValue) == "(keins ausgewählt)")
{
return;
}
else
{
string land = "";
land = txtLand.SelectedValue.ToString();
getStadt(land);
//Console.WriteLine(wetterObjekt.GetCitiesByCountry(land));
//Console.WriteLine(land);
}
}
private void getStadt (string land)
{
XmlDocument document = new XmlDocument();
document.LoadXml(wetterObjekt.GetCitiesByCountry(land));
XmlNodeList nl = document.GetElementsByTagName("NewDataSet");
for (int x = 0; x < nl[0].ChildNodes.Count; x++)
{
for (int y = 1; y < nl[0].ChildNodes[x].ChildNodes.Count; y += 2)
{
cityList.Add(nl[0].ChildNodes[x].ChildNodes[y].InnerText);
}
}
cityList.Sort();
for (int x = 0; x < cityList.Count; x++)
{
txtStadt.Items.Add(cityList[x]);
}
}
private void getCountries()
{
string countries = country.GetCountries ();
XmlDocument document = new XmlDocument ();
document.LoadXml ( countries );
XmlNodeList nl = document.GetElementsByTagName ( "NewDataSet" );
string firstStr = "(keins ausgewählt)";
object firstItem = firstStr;
txtLand.Items.Add(firstItem);
for ( int x = 0; x < nl [0].ChildNodes.Count; x++ )
{
for ( int y = 0; y < nl [0].ChildNodes [x].ChildNodes.Count; y++ )
{
countryList.Add ( nl [0].ChildNodes [x].ChildNodes [y].InnerText );
}
}
for ( int i = 0; i < countryList.Count; i++ )
{
txtLand.Items.Add ( countryList [i] );
}
}
private void getWeather ( string stadt, string land )
{
try
{
wetter = wetterObjekt.GetWeather(stadt, land);
xmlParsen(wetter);
txtWetter.Text = wetterAktuell;
}
catch (System.Xml.XmlException e)
{
clearWetterTextBox();
txtWetter.Text = "Keine Wetterdaten gefunden!";
//Console.WriteLine("Keine Wetterdaten gefunden!");
}
}
private void btnSchliessen_Click ( object sender, RoutedEventArgs e )
{
this.Close ();
}
private void xmlParsen (string wetter)
{
XmlDocument document = new XmlDocument ();
try
{
document.LoadXml(wetter);
XmlNodeList nl = document.GetElementsByTagName("CurrentWeather");
for (int i = 0; i < nl[0].ChildNodes.Count; i++)
{
wetterAktuell = wetterAktuell + (nl[0].ChildNodes[i].Name + ": " + nl[0].ChildNodes[i].InnerText) + "\n";
}
}
catch (System.Xml.XmlException e)
{
throw new System.Xml.XmlException();
}
}
private void btnGetWetter_Click ( object sender, RoutedEventArgs e )
{
clearWetterTextBox ();
getWeather (txtStadt.Text, txtLand.Text);
}
private void clearWetterTextBox ()
{
wetterAktuell = "";
this.txtWetter.Clear ();
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
}
}

Related

Multiline textbox entries not seperated

why other strings other than -ABC12 are not separated?
enter code here
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace multiline_textbox_seperation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
String[] lines = textBox2.Text.Split(',');
List<string> List = new List<string>();
List.AddRange(lines);
for (int i = 0; i < List.Count; i++)
{
textBox1.Text += List[i] + "\r\n";
}
List<String> PossitiveList = new List<String> { };
List<String> NegativeList = new List<String> { };
for (int i = 0; i < List.Count; i++)
{
if (List[i].StartsWith("-")) { NegativeList.Add(List[i]); }
if (List[i].StartsWith("+")) { PossitiveList.Add(List[i]); }
}
listBox1.DataSource = NegativeList;
listBox2.DataSource = PossitiveList;
}
}
}
the result for the string:
string input = "-ABC12, +ABC12, -BAC12, -ACC12, +EAC12, -BBC12, -CBC12, +GABC12, +ACC12, +CBC12, +BBC12"
typed in textbox2 is:
If you look closely, you have spaces in between.
Instead of doing: List[i].StartsWith("-") or List[i].StartsWith("+"), do a:
List[i].Trim().StartsWith("-")
List[i].Trim().StartsWith("+")
I'd simplify a bit with:
private void button1_Click(object sender, EventArgs e)
{
var values = new List<string>(textBox2.Text.Split(','))
.Select(x => x.Trim()).ToList();
textBox1.Lines = values.ToArray(); // optional
var PositiveList = values.Where(x => x.StartsWith("+")).ToList();
var NegativeList = values.Where(x => x.StartsWith("-")).ToList();
listBox1.DataSource = NegativeList;
listBox2.DataSource = PositiveList;
}

How do make the code display the information?

I'm trying to debug the C# code but can't find the logic error of why it's not displaying the data and no error message.
To begin with, the code was in large chunks so I then tried splitting the code into smaller methods but still unable to find the issue of where I'm going wrong.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Drivers_license_exam
{
public partial class Form1 : Form
{
private string[] studentAnsArray = new string[20];
private string[] correctAnsArray = { "B", "D", "A", "A", "C", "A","B", "A", "C", "D", "B","C",
"D", "A", "D", "C","C", "B", "D", "A" };
public Form1()
{
InitializeComponent();
}
private void GetFile(out string fileName)
{
if (openFile.ShowDialog() == DialogResult.OK)
{
fileName = openFile.FileName;
}
else
{
fileName = "";
}
}
private void GetAndReadFile(string fileName)
{
string results;
StreamReader inputFile = File.OpenText(fileName);
while (!inputFile.EndOfStream)
{
results = inputFile.ReadLine();
studentAns.Items.Add(results);
//studentAnsArray[index] = inputFile.ReadLine();
//correctAns.Items.Add(studentAnsArray);
}
foreach (string answers in correctAnsArray)
{
correctAns.Items.Add(answers);
}
inputFile.Close();
}
private int TotCorrect()
{
int correct = 0;
for (int index = 0; index < correctAnsArray.Length; index++)
{
if (studentAnsArray[index]== correctAnsArray[index])
{
correctTxt.Text = index.ToString();
correct++;
}
}
return correct;
}
private int TotIncorrect()
{
int incorrect = 0, questNum = 1;
for (int index = 0; index < correctAnsArray.Length; index++)
{
if (studentAnsArray[index] == correctAnsArray[index])
{
incorrectAns.Items.Add("Question: " + questNum);
incorrectAns.Items.Add("Incorrect");
incorrect++;
}
}
return incorrect;
}
private bool PassedTest()
{
bool pass = false;
if (TotCorrect() >= 15)
{
passFailedTxt.Text = "Passed";
}
if (TotIncorrect() < 15)
{
passFailedTxt.Text = "Failed";
}
return pass;
}
private void displayRes_Click(object sender, EventArgs e)
{
string studentAns;
GetFile(out studentAns);
GetAndReadFile(studentAns);
TotCorrect();
TotIncorrect();
PassedTest();
}
private void exit_Click(object sender, EventArgs e)
{
this.Close();
}
private void Clear_Click(object sender, EventArgs e)
{
}
}
}
What I expected the code to do is output the following:
display the incorrect results
display pass or fail in a text box
display the total of correct and incorrect answers in a text box
The output that I'm getting from this code is:
- doesn't display the incorrect answers in the list box
- displays fail although the answers from the text and the array are correct
- doesn't display the total of correct and incorrect answers

Is that logic to reset the Lists and call Init() over again if there was an exception with the download/s?

And how can i report to the user that there was a problem and that it's trying over again ? And should i just do it like i'm doing it now reseting everything and calling Init() again or should i use some timer and wait some seconds before trying again ?
In the class i did:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Xml;
using HtmlAgilityPack;
using System.ComponentModel;
namespace TestingDownloads
{
class ExtractImages
{
static WebClient client;
static string htmltoextract;
public static List<string> countriescodes = new List<string>();
public static List<string> countriesnames = new List<string>();
public static List<string> DatesAndTimes = new List<string>();
public static List<string> imagesUrls = new List<string>();
static string firstUrlPart = "http://www.sat24.com/image2.ashx?region=";
static string secondUrlPart = "&time=";
static string thirdUrlPart = "&ir=";
public class ProgressEventArgs : EventArgs
{
public int Percentage { get; set; }
public string StateText { get; set; }
}
public event EventHandler<ProgressEventArgs> ProgressChanged;
public void Init()
{
object obj = null;
int index = 0;
ExtractCountires();
foreach (string cc in countriescodes)
{
// raise event here
ProgressChanged?.Invoke(obj,new ProgressEventArgs{ Percentage = 100 * index / countriescodes.Count, StateText = cc });
ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
index +=1;
}
ImagesLinks();
}
public void ExtractCountires()
{
try
{
htmltoextract = "http://sat24.com/en/?ir=true";//"http://sat24.com/en/";// + regions;
client = new WebClient();
client.DownloadFile(htmltoextract, #"c:\temp\sat24.html");
client.Dispose();
string tag1 = "<li><a href=\"/en/";
string tag2 = "</a></li>";
string s = System.IO.File.ReadAllText(#"c:\temp\sat24.html");
s = s.Substring(s.IndexOf(tag1));
s = s.Substring(0, s.LastIndexOf(tag2) + tag2.ToCharArray().Length);
s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
string[] parts = s.Split(new string[] { tag1, tag2 }, StringSplitOptions.RemoveEmptyEntries);
string tag3 = "<li><ahref=\"/en/";
for (int i = 0; i < parts.Length; i++)
{
if (i == 17)
{
//break;
}
string l = "";
if (parts[i].Contains(tag3))
l = parts[i].Replace(tag3, "");
string z1 = l.Substring(0, l.IndexOf('"'));
if (z1.Contains("</ul></li><liclass="))
{
z1 = z1.Replace("</ul></li><liclass=", "af");
}
countriescodes.Add(z1);
countriescodes.GroupBy(n => n).Any(c => c.Count() > 1);
string z2 = parts[i].Substring(parts[i].LastIndexOf('>') + 1);
if (z2.Contains("&"))
{
z2 = z2.Replace("&", " & ");
}
countriesnames.Add(z2);
countriesnames.GroupBy(n => n).Any(c => c.Count() > 1);
}
}
catch (Exception e)
{
if (countriescodes.Count == 0)
{
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
Init();
}
}
}
public void ExtractDateAndTime(string baseAddress)
{
try
{
var wc = new WebClient();
wc.BaseAddress = baseAddress;
HtmlDocument doc = new HtmlDocument();
var temp = wc.DownloadData("/en");
doc.Load(new MemoryStream(temp));
var secTokenScript = doc.DocumentNode.Descendants()
.Where(e =>
String.Compare(e.Name, "script", true) == 0 &&
String.Compare(e.ParentNode.Name, "div", true) == 0 &&
e.InnerText.Length > 0 &&
e.InnerText.Trim().StartsWith("var region")
).FirstOrDefault().InnerText;
var securityToken = secTokenScript;
securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
foreach (var date in scriptDates)
{
DatesAndTimes.Add(date.DateString);
}
}
catch
{
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
this.Init();
}
}
public class ScriptDate
{
public string DateString { get; set; }
public int Year
{
get
{
return Convert.ToInt32(this.DateString.Substring(0, 4));
}
}
public int Month
{
get
{
return Convert.ToInt32(this.DateString.Substring(4, 2));
}
}
public int Day
{
get
{
return Convert.ToInt32(this.DateString.Substring(6, 2));
}
}
public int Hours
{
get
{
return Convert.ToInt32(this.DateString.Substring(8, 2));
}
}
public int Minutes
{
get
{
return Convert.ToInt32(this.DateString.Substring(10, 2));
}
}
}
public void ImagesLinks()
{
int cnt = 0;
foreach (string countryCode in countriescodes)
{
cnt++;
for (; cnt < DatesAndTimes.Count(); cnt++)
{
string imageUrl = firstUrlPart + countryCode + secondUrlPart + DatesAndTimes[cnt] + thirdUrlPart + "true";
imagesUrls.Add(imageUrl);
if (cnt % 10 == 0) break;
}
}
}
}
}
In both cases where i'm using try and catch if it's getting to the catch i'm trying over again the whole operation by reseting the Lists and calling Init() again.
Then in form1
ExtractImages ei = new ExtractImages();
public Form1()
{
InitializeComponent();
ProgressBar1.Minimum = 0;
ProgressBar1.Maximum = 100;
backgroundWorker1.RunWorkerAsync();
}
events of backgroundworker
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return; // this will fall to the finally and close everything
}
else
{
ei.ProgressChanged += (senders, eee) => backgroundWorker1.ReportProgress(eee.Percentage, eee.StateText);
ei.Init();
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressBar1.Value = e.ProgressPercentage;
label7.Text = e.UserState.ToString();
label8.Text = e.ProgressPercentage + "%";
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
ProgressBar1.Value = 100;
}
else
{
}
}
Another thing not sure if it's a problem. When there is no a problem with the class i see in form1 in label7 all the codes running from the first to the last.
But the progressBar1.Value and label8 both are getting only to 97% so i need in the completed event to add the progressBar1.Value = 100; is that fine or there is a problem with the reporting calculation in the class ?
For the 1st question:
Better catch the exception at client side and display the error msg, 'cause you probably need to control your program behavior accrodingly when sth went wrong.
Consider this: if the DOM struct of the page changed, according to you code, your program probably throw expections, with each exception catching, client.DownloadFile is excuted for one time, if this happens, u will need to know what go wrong, and if u donot change ur code behavior, such hi-freq client.DownloadFile excution will cause the firewall of the website block ur ip for a while.
Add a timer at client side is a good idea i think.
For the 2nd one:
did u define how to handle RunWorkerCompleted event?

How to update a TextView text (decode text effect)?

I need help as mentioned in the title.
I have a timer routine that will update the text of a label. It's a decode text effect, but it doesn't seem to update when the timer routine is executed. I am using C#.
MainActivity.cs
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Text;
using System.Timers;
using System.Linq;
namespace ValidateCreditCardNumber_Android
{
[Activity (Label = "ValidateCreditCardNumber_Android", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
EditText editText;
DecodeTextView resultLabel;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
editText = FindViewById<EditText> (Resource.Id.editText);
Button validateButton = FindViewById<Button> (Resource.Id.validateButton);
resultLabel = FindViewById<DecodeTextView> (Resource.Id.resultLabel);
editText.KeyListener = Android.Text.Method.DigitsKeyListener.GetInstance("0123456789" + System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits);
validateButton.Click += OnNumberEntryCompleted;
}
void OnNumberEntryCompleted(object sender, EventArgs args)
{
var entry = editText;
var resultText = "";
if (Mod10Check (entry.Text)) {
// resultLabel.SetTextColor(Android.Graphics.Color.White);
resultText = "__VALID NUMBER";
} else {
resultText = "INVALID NUMBER";
}
// entry.Enabled = false;
// resultLabel.AnimateText (true, resultText, 10);
RunOnUiThread(() => resultLabel.AnimateText (true, resultText, 10));
}
public static bool Mod10Check(string creditCardNumber)
{
// Check whether input string is null or empty.
if (string.IsNullOrEmpty(creditCardNumber)) {
return false;
}
char[] charArray = creditCardNumber.ToCharArray();
// 1. Starting with the check digit double the value of every other digit
// 2. If doubling of a number results in a two digits number, add up.
// the digits to get a single digit number. This will results in eight single digit numbers.
// 3. Get the sum of the digits.
int sumOfDigits = charArray.Where((e) => e >= '0' && e <= '9')
.Reverse()
.Select((e, i) => ((int)e - 48) * (i % 2 == 0 ? 1 : 2))
.Sum((e) => e / 10 + e % 10);
// If the final sum is divisible by 10, then the credit card number.
// is valid. If it is not divisible by 10, the number is invalid.
return sumOfDigits % 10 == 0;
}
}
}
DecodeTextView.cs
using System;
using System.Text;
using System.Timers;
//using Android.Runtime;
using Android.Content;
using Android.Util;
namespace ValidateCreditCardNumber_Android
{
public class DecodeTextView : Android.Widget.TextView
{
private readonly Timer _timerAnimate = new Timer();
private TextDecodeEffect _decodeEffect;
private bool _showing;
private int _initGenCount;
public int Interval
{
get { return (int)_timerAnimate.Interval; }
set { _timerAnimate.Interval = value; }
}
// protected DecodeTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
public DecodeTextView(Context c, IAttributeSet args) : base(c, args)
{
_timerAnimate.Interval = 100;
_timerAnimate.Elapsed += _timerAnimate_Tick;
}
public void AnimateText(bool show, string text, int initGenCount)
{
_initGenCount = initGenCount;
_decodeEffect = new TextDecodeEffect(text) { TextVisible = !show };
Text = _decodeEffect.Peek (DecodeMode.None);
_showing = show;
_timerAnimate.Start ();
}
private void _timerAnimate_Tick(object sender, EventArgs e)
{
if (_initGenCount != 0) {
Text = _decodeEffect.GenerateNumberRange (Text.Length);
_initGenCount--;
return;
}
var decodeMode = _showing ? DecodeMode.Show : DecodeMode.Hide;
var text = _decodeEffect.Peek (decodeMode);
if (text == null) {
_timerAnimate.Stop ();
} else {
Text = text;
}
}
}
public enum DecodeMode
{
None,
Show,
Numbers,
Hide
}
class TextDecodeEffect
{
private int _visibleCount;
private readonly Random _random = new Random ();
public bool TextVisible
{
get { return _visibleCount == OriginalText.Length; }
set { _visibleCount = value ? OriginalText.Length : 0; }
}
public string OriginalText { get; private set; }
public TextDecodeEffect(string text)
{
OriginalText = text;
}
public string Peek(DecodeMode mode)
{
switch (mode) {
case DecodeMode.Numbers:
return GenerateNumberRange (OriginalText.Length);
case DecodeMode.Hide:
if (_visibleCount == 0)
return null;
_visibleCount--;
break;
case DecodeMode.Show:
if (_visibleCount == OriginalText.Length)
return null;
_visibleCount++;
break;
}
var text = GenerateNumberRange (OriginalText.Length - _visibleCount);
text += OriginalText.Substring (OriginalText.Length - _visibleCount, _visibleCount);
return text;
}
public string GenerateNumberRange(int count)
{
var SB = new StringBuilder ();
for (int i = 0; i < count; i++)
SB.Append(_random.Next(0, 10));
return SB.ToString();
}
}
}
Here you can found the project
Please help me to fix this problem :( thank you.
This is a threading issue, you can only change UI elements on the UI thread and the timer callback _timerAnimate_Tick will execute on a background thread.
You can see this by logging the thread ID for DecodeTextViews constructor and its _timerAnimate_Tick method:
public DecodeTextView(Context c, IAttributeSet args) : base(c, args)
{
// ...
Console.WriteLine ("DecodeTextView executing on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
}
private void _timerAnimate_Tick(object sender, EventArgs e)
{
Console.WriteLine ("_timerAnimate_Tick executing on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
// ...
}
Which will render the following in the log output:
DecodeTextView executing on thread: 1
_timerAnimate_Tick executing on thread: 6
This is simply fixed by changing the Text property of DecodeTextView on the UI thread using the Post method:
private void _timerAnimate_Tick(object sender, EventArgs e)
{
if (_initGenCount != 0) {
Post (() => {
Text = _decodeEffect.GenerateNumberRange (Text.Length);
});
_initGenCount--;
return;
}
var decodeMode = _showing ? DecodeMode.Show : DecodeMode.Hide;
var text = _decodeEffect.Peek (decodeMode);
if (text == null) {
_timerAnimate.Stop ();
} else {
Post (() => {
Text = text;
});
}
}

How do i loop through two Lists to compare items in both Lists?

I have this code:
private void removeDuplicates(List<string> currentSites, List<string> visitedSites)
{
for (int i = 0; i < currentSites.Count; i++)
{
for (int x = 0; x < visitedSites.Count; x++)
{
}
}
}
Im getting two Lists and i need first to compare each item in one List to the items in the other List to loop over all the items in the other List and compare. If one of the items exist in the other List mark it as NULL.
I need to check that visitedSites are in the currentSites to take one item move over all the Lists to check if exit if it is to mark as null.
In any case i need to use two loop's one ine the other one.
When i find its null to mark it null and after it make break;
Then i need to add another loop FOR to move over the List currentSites if im not wrong and remove all the marked NULL items.
The idea is to compare the Lists by mark the duplicated items as null then to remove all the null's.
This is the code from the beginning:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Net;
using System.Web;
namespace GatherLinks
{
public partial class Form1 : Form
{
List<string> currentCrawlingSite;
List<string> sitesToCrawl;
int actual_sites;
BackgroundWorker worker;
int sites = 0;
int y = 0;
string guys = "http://www.google.com";
public Form1()
{
InitializeComponent();
currentCrawlingSite = new List<string>();
sitesToCrawl = new List<string>();
actual_sites = 0;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private List<string> getLinks(HtmlAgilityPack.HtmlDocument document)
{
List<string> mainLinks = new List<string>();
var linkNodes = document.DocumentNode.SelectNodes("//a[#href]");
if (linkNodes != null)
{
foreach (HtmlNode link in linkNodes)
{
var href = link.Attributes["href"].Value;
mainLinks.Add(href);
}
}
return mainLinks;
}
private List<string> webCrawler(string url, int levels , DoWorkEventArgs eve)
{
HtmlAgilityPack.HtmlDocument doc;
HtmlWeb hw = new HtmlWeb();
List<string> webSites;// = new List<string>();
List<string> csFiles = new List<string>();
csFiles.Add("temp string to know that something is happening in level = " + levels.ToString());
csFiles.Add("current site name in this level is : " + url);
try
{
doc = hw.Load(url);
currentCrawlingSite.Add(url);
webSites = getLinks(doc);
removeDuplicates(currentCrawlingSite, webSites);
removeDuplicates(currentCrawlingSite, sitesToCrawl);
sitesToCrawl = webSites;
if (levels == 0)
{
return csFiles;
}
else
{
for (int i = 0; i < webSites.Count() && i < 20; i++) {
int mx = Math.Min(webSites.Count(), 20);
if ((worker.CancellationPending == true))
{
eve.Cancel = true;
break;
}
else
{
string t = webSites[i];
if ((t.StartsWith("http://") == true) || (t.StartsWith("https://") == true))
{
actual_sites++;
csFiles.AddRange(webCrawler(t, levels - 1,eve));
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, "Level Number " + levels + " " + t + Environment.NewLine, Color.Red); }));
worker.ReportProgress(Math.Min((int)((double)i / mx * 100),100));
}
}
}
return csFiles;
}
}
catch
{
return csFiles;
}
}
So im calling the removeDuplicated function twice need to do in the removeDuplicated the things i wrote above then im not sure if to do sitesToCrawl = webSites; or ot add somehow the links in webSites to the sitesToCrawl. The idea is when i loop over the webSites that there will be no duplicated items when adding to the csFiles List.
Not sure if I understand your problem:
IEnumerable<string> notVisitedSites = currentSites.Except(visitedSites);

Categories