using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using System.Globalization; using System.Resources; namespace EduNetworkBuilder { public partial class ListBoxWindow : Form { class MyPuzzleEntry { public string Title; public string PuzzleName; public bool isdone = false; public string level = ""; public bool InRegressionMode = false; public bool HasTest = false; public bool PassedTest = false; public bool FailedTest = false; public override string ToString() { string donstr = ""; if (InRegressionMode) { if (HasTest) donstr = "+ "; else donstr = "- "; if (PassedTest) donstr = "$ "; if (FailedTest) donstr = "X "; return donstr + level + " " + this.Title; } else { if (isdone) donstr = "* "; return donstr + level + " " + this.Title; } } } protected LBContents MyMode = LBContents.messages; protected DebugLevel WhatToDisplay = DebugLevel.info; //used when viewing packet-messages NetworkDevice myNetDevice; PacketMessage myPacketMessage; int EditableCount = -1; bool processing = false; string FilterString = ""; string TestString = "Test"; string NoTestString = "No Test"; string PassedString = "Passed"; string FailedString = "Failed"; string Untested = "Untested"; public bool ClosingRegression = false; /// /// Instantiate a ListBoxWindow for use in choosing a network to load /// public ListBoxWindow() { InitializeComponent(); LanguagifyComponents(); MyMode = LBContents.puzzles; UpdateForm(); CheckBox newCB; btnAdd.Visible = false; int count = 0; lblInstructions.Text = NB.Translate("LBW_LBWFilter"); panelCheckboxes.SuspendLayout(); string SelectedTag = GetSelectedTag(); tbSearchBox.Visible = true; if (SelectedTag == NB.Translate("_All")) Text = Text + NB.Translate("_AllS"); NBSettings oursettings = NB.GetSettings(); foreach (string str in NB.GetPuzzleTags()) { newCB = AddCheckBox(count, str); if (str == SelectedTag || (SelectedTag == "ALL" && Regex.IsMatch(str,"Level"))) { newCB.Checked = true; //The first level with an unsolved puzzle starts checked } else { newCB.Checked = false; } count++; } panelCheckboxes.ResumeLayout(); btnOK.Text = NB.Translate("_Load"); btnAdd.Text = NB.Translate("_Cancel"); btnAdd.Visible = true; cbLoadPuzzlesAtStart.Checked = oursettings.AutoStartPuzzles; Text = NB.Translate("NB_puzzlesToolStripMenuItem"); //"Puzzles UpdateForm(); } /// /// We are doing a routing table or dhcp. We pass it the device and pull the data from that /// /// The master device to edit/view the routing table of public ListBoxWindow(NetworkDevice MasterDevice, LBContents mode) { InitializeComponent(); LanguagifyComponents(); tbSearchBox.Visible = false; if (mode == LBContents.routes) { MyMode = LBContents.routes; myNetDevice = MasterDevice; lblInstructions.Text = NB.Translate("LBW_LBWDblClckRout"); lbWindowData.Font = new System.Drawing.Font("Courier New", 8); btnAdd.Visible = true; Text = NB.Translate("DC_btnRoutes"); //Routes } if (mode == LBContents.dhcp) { MyMode = LBContents.dhcp; myNetDevice = MasterDevice; lblInstructions.Text = NB.Translate("LBW_LBWDblClckIf"); lbWindowData.Font = new System.Drawing.Font("Courier New", 8); btnAdd.Visible = false; Text = NB.Translate("H_DHCP_Title"); //DHCP } if(mode == LBContents.regressiontest) { MyMode = LBContents.regressiontest; //Regression testing. Similar to listing all the puzzles. Text = NB.Translate("LBW_Regression_Testing"); //Regression Testing // lblInstructions.Text = ""; UpdateForm(); CheckBox newCB; int count = 0; panelCheckboxes.SuspendLayout(); string SelectedTag = GetSelectedTag(); tbSearchBox.Visible = true; if (SelectedTag == NB.Translate("_All")) Text = Text + NB.Translate("_AllS"); NBSettings oursettings = NB.GetSettings(); foreach (string str in NB.GetPuzzleTags()) { newCB = AddCheckBox(count, str); count++; } newCB = AddCheckBox(count++, TestString); newCB = AddCheckBox(count++, NoTestString); newCB = AddCheckBox(count++, PassedString); newCB = AddCheckBox(count++, FailedString); newCB.Checked = true; //start with "Failed" checked newCB = AddCheckBox(count++, Untested); newCB.Checked = true; //start with "Untested" checked this.ControlBox = false; //remove the X at the top corner that gives us problems panelCheckboxes.ResumeLayout(); btnOK.Text = NB.Translate("_Load"); btnAdd.Text = NB.Translate("_Cancel"); btnAdd.Visible = true; } UpdateForm(); } /// /// We are doing a packet message detail look. /// /// The packet message to look at public ListBoxWindow(PacketMessage Messages) { InitializeComponent(); LanguagifyComponents(); MyMode = LBContents.messages; myPacketMessage = Messages; UpdateForm(); btnAdd.Visible = false; int count=0; lblInstructions.Text = NB.Translate("LBW_LBWDetail"); panelCheckboxes.SuspendLayout(); Text = NB.Translate("H_Packet_Title"); //Packet foreach (string str in Enum.GetNames(typeof(DebugLevel))) { AddCheckBox(count, str); count++; } panelCheckboxes.ResumeLayout(); UpdateChecked(); } private void LanguagifyComponents() { Text = NB.Translate("_OK"); Text = NB.Translate("LBW_lblInstructions"); Text = NB.Translate("LBW_btnAdd"); Text = NB.Translate("LBW_cbLoadPuzzlesAtStart"); Text = NB.Translate("LBW_btnReset"); Text = NB.Translate("LBW_Form"); } private CheckBox AddCheckBox(int count, string name) { int myY = 1; int myX = 1; int cdwidth = 70; int cdHeight = 20; int divisor = panelCheckboxes.Width / cdwidth; myX = (cdwidth * count) % (divisor * cdwidth); myY = ((cdwidth * count) / (divisor * cdwidth)) * cdHeight; CheckBox newCB = new CheckBox(); newCB.Text = name; Point mylocation = new Point(myX, myY); newCB.AutoSize = true; newCB.Name = "checkBox" + count.ToString(); newCB.Size = new System.Drawing.Size(98, 21); newCB.TabIndex = count; newCB.UseVisualStyleBackColor = true; newCB.Location = mylocation; newCB.CheckedChanged += genericCheckmarkChange; panelCheckboxes.Controls.Add(newCB); return newCB; } private string GetSelectedTag() { PuzzleInfo PI; string first = ""; NBSettings oursettings = NB.GetSettings(); string OriginalChoice = oursettings.ProcessingLevel; if(OriginalChoice != null) { if (NB.PuzzleLevelHasUnsolved(OriginalChoice)) return OriginalChoice; } foreach (string str in NB.GetPuzzleNames()) { if(!oursettings.ScoreList.Contains(str)) { PI = NB.GetPuzzleInfoFromName(str); first = PI.strLevel; break; } } if (first != "") return first; return NB.Translate("_All"); } private void UpdateForm() { int selectedIndex = lbWindowData.SelectedIndex; int FirstUnfinishedIndex = -1; string selected = ""; int topmost = lbWindowData.TopIndex; int totalcount = lbWindowData.Items.Count; if (lbWindowData.SelectedIndex != -1) selected = lbWindowData.Items[lbWindowData.SelectedIndex].ToString(); lbWindowData.Items.Clear(); cbLoadPuzzlesAtStart.Visible = false; btnReset.Visible = false; List itemstrings = new List(); if (MyMode == LBContents.messages) { itemstrings.AddRange(myPacketMessage.GetMessagesSummary()); itemstrings.AddRange(myPacketMessage.GetMessagesLike(WhatToDisplay)); foreach (string str in itemstrings) { lbWindowData.Items.Add(str); } } if(MyMode == LBContents.routes) { itemstrings.Add(NB.Translate("LBW_UpdateFormStatRout")); itemstrings.AddRange(myNetDevice.DeviceRouteStrings()); EditableCount = itemstrings.Count(); itemstrings.Add(NB.Translate("LBW_UpdateFormNICRout")); itemstrings.AddRange(myNetDevice.NICRouteStrings()); foreach (string str in itemstrings) { lbWindowData.Items.Add(str); } } if (MyMode == LBContents.dhcp) { myNetDevice.CheckDHCPRangesAgainstInterfaces(); itemstrings.AddRange(myNetDevice.DHCPStrings()); foreach (string str in itemstrings) { lbWindowData.Items.Add(str); } } if (MyMode == LBContents.puzzles) { cbLoadPuzzlesAtStart.Visible = true; btnReset.Visible = true; PuzzleInfo pi; string shown_name; string puzzle_name=""; List Puzzles = NB.GetPuzzleNames(); NBSettings oursettings = NB.GetSettings(); if (Puzzles == null) return; bool wasfinished = false; foreach (string str in Puzzles) { wasfinished = false; if (FilterString == "") { pi = NB.GetPuzzleInfoFromName(str); //shown_name = pi.PuzzleName; shown_name = pi.NetTitle.GetText(); puzzle_name = pi.PuzzleName; if (oursettings.CheckIfDone(str)) { wasfinished = true; } foreach (string tag in pi.PuzzleTags) { if (isChecked(tag)) { MyPuzzleEntry MPE = new MyPuzzleEntry(); MPE.PuzzleName = puzzle_name; MPE.Title = shown_name; MPE.isdone = wasfinished; MPE.level = tag; if(selected == "" && !wasfinished) selected = shown_name; //Select the first unfinished puzzle lbWindowData.Items.Add(MPE); break; } } if (!wasfinished && FirstUnfinishedIndex == -1) FirstUnfinishedIndex = lbWindowData.Items.Count - 1; } else { //We are filtering stuff pi = NB.GetPuzzleInfoFromName(str); //shown_name = pi.PuzzleName; shown_name = pi.NetTitle.GetText(); bool added = false; string localFilter = ".*" + FilterString + ".*"; if (oursettings.ScoreList.Contains(str)) { wasfinished = true; } MyPuzzleEntry MPE = new MyPuzzleEntry(); MPE.PuzzleName = puzzle_name; MPE.Title = shown_name; MPE.isdone = wasfinished; MPE.level = "Level_" + pi.Level; if (!added && pi.PuzzleName != null && Regex.IsMatch(pi.PuzzleName, localFilter, RegexOptions.IgnoreCase)) { added = true; lbWindowData.Items.Add(MPE); } if (!added && pi.PuzzleDescription!= null && Regex.IsMatch(pi.PuzzleDescription, localFilter, RegexOptions.IgnoreCase)) { added = true; lbWindowData.Items.Add(MPE); } if (!added && pi.PuzzleTitle != null && Regex.IsMatch(pi.PuzzleTitle, localFilter,RegexOptions.IgnoreCase)) { added = true; lbWindowData.Items.Add(MPE); } foreach (string tag in pi.PuzzleTags) { if (!added && pi.PuzzleTitle != null && Regex.IsMatch(tag, localFilter, RegexOptions.IgnoreCase)) { if (selected == "" && !wasfinished) selected = shown_name; //Select the first unfinished puzzle lbWindowData.Items.Add(MPE); break; } } } } if(selected != null && selected != "") { if (selectedIndex >= 0 && selectedIndex < lbWindowData.Items.Count) { lbWindowData.SelectedIndex = selectedIndex; lbWindowData.TopIndex = topmost; } } if(lbWindowData.SelectedIndex == -1 && FirstUnfinishedIndex != -1 ) { if(lbWindowData.Items.Count > FirstUnfinishedIndex) lbWindowData.SelectedIndex = FirstUnfinishedIndex; //Select the first unselected item if nothing else was selected } if(lbWindowData.SelectedIndex != -1) { btnOK.Enabled = true; } else { btnOK.Enabled = false; } } if (MyMode == LBContents.regressiontest) { cbLoadPuzzlesAtStart.Visible = false; btnReset.Visible = true; btnReset.Text = "Close"; tbSearchBox.Visible = false; btnAdd.Text = "Test All"; btnOK.Text = "Test One"; PuzzleInfo pi; string shown_name; string puzzle_name = ""; List Puzzles = NB.GetPuzzleNames(); NBSettings oursettings = NB.GetSettings(); if (Puzzles == null) return; bool wasfinished = false; int count = 0; foreach (string str in Puzzles) { wasfinished = false; pi = NB.GetPuzzleInfoFromName(str); //shown_name = pi.PuzzleName; shown_name = pi.NetTitle.GetText(); puzzle_name = pi.PuzzleName; if (oursettings.CheckIfDone(str)) { wasfinished = true; } List tags = new List(pi.PuzzleTags); if(oursettings.HasReplay(puzzle_name)) tags.Add(TestString); else tags.Add(NoTestString); if (oursettings.HasPassed(puzzle_name)) tags.Add(PassedString); if (oursettings.HasFailed(puzzle_name)) tags.Add(FailedString); if (oursettings.HasPassed(puzzle_name)) tags.Add(PassedString); if (!oursettings.HasFailed(puzzle_name) && !oursettings.HasPassed(puzzle_name) && oursettings.HasReplay(puzzle_name)) tags.Add(Untested); foreach (string tag in tags) { if (isChecked(tag)) { MyPuzzleEntry MPE = new MyPuzzleEntry(); MPE.PuzzleName = puzzle_name; MPE.Title = shown_name; MPE.isdone = wasfinished; MPE.level = pi.strLevel; MPE.InRegressionMode = true; if (oursettings.HasPassed(puzzle_name)) MPE.PassedTest = true; if (oursettings.HasFailed(puzzle_name)) MPE.FailedTest = true; MPE.HasTest = oursettings.HasReplay(puzzle_name); if (selected == "" && !wasfinished) selected = shown_name; //Select the first unfinished puzzle lbWindowData.Items.Add(MPE); if(MPE.HasTest) count++; //we can only test-all if there are tests to do break; } } } if (selected != null && selected != "") { if (selectedIndex >= 0 && selectedIndex < lbWindowData.Items.Count) { lbWindowData.SelectedIndex = selectedIndex; lbWindowData.TopIndex = topmost; } } if (lbWindowData.SelectedIndex != -1) { btnOK.Enabled = true; } else { btnOK.Enabled = false; } if (count > 0) btnAdd.Enabled = true; else btnAdd.Enabled = false; } } private void btnOK_Click(object sender, EventArgs e) { NBSettings oursettings = NB.GetSettings(); if (MyMode == LBContents.puzzles && lbWindowData.SelectedItem != null) { if (lbWindowData.SelectedItem is string) { string TheName = lbWindowData.SelectedItem.ToString(); TheName = Regex.Replace(TheName, @"^\* ", ""); Visible = false; BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) { myWin.Activate(); } if (oursettings.AutoStartPuzzles != cbLoadPuzzlesAtStart.Checked) { oursettings.AutoStartPuzzles = cbLoadPuzzlesAtStart.Checked; // oursettings.Save(); } if (lbWindowData.SelectedItem != null) NB.LoadNetworkFromResource(TheName); } else if (lbWindowData.SelectedItem is MyPuzzleEntry) { MyPuzzleEntry MPE = (MyPuzzleEntry)lbWindowData.SelectedItem; string TheName = MPE.PuzzleName; Visible = false; BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) { myWin.Activate(); } if (oursettings.AutoStartPuzzles != cbLoadPuzzlesAtStart.Checked) { oursettings.AutoStartPuzzles = cbLoadPuzzlesAtStart.Checked; // oursettings.Save(); } if (lbWindowData.SelectedItem != null) NB.LoadNetworkFromResource(TheName); } Close(); } else if (MyMode == LBContents.regressiontest) { if (lbWindowData.SelectedItem is MyPuzzleEntry) { MyPuzzleEntry MPE = (MyPuzzleEntry)lbWindowData.SelectedItem; string TheName = MPE.PuzzleName; //Visible = false; BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin != null) { if (oursettings.HasReplay(TheName)) { //myWin.Activate(); FormColorForTesting(); myWin.replayNetwork(TheName, 1); //Return back to the listbox window Visible = true; Activate(); FormColorBackToNormal(); } else { if (lbWindowData.SelectedItem != null) { NB.LoadNetworkFromResource(TheName); } } } UpdateForm(); //If anything changed, show it } } else Close(); } private void FormColorForTesting() { this.BackColor = Color.GreenYellow; Refresh(); } private void FormColorBackToNormal() { this.BackColor = SystemColors.Control; Refresh(); } private void FormColorContinuingLoop() { this.BackColor = Color.DarkGray; Refresh(); } /// /// The checkmark was changed. Tally up everything /// /// The checkmark that changed /// private void genericCheckmarkChange(object sender, EventArgs e) { if (processing) return; CheckBox mybox = (CheckBox)sender; if (MyMode == LBContents.messages) { if (mybox.Checked) { WhatToDisplay = WhatToDisplay | NB.ParseEnum(mybox.Text); } else { WhatToDisplay = WhatToDisplay ^ NB.ParseEnum(mybox.Text); } } UpdateChecked(); } private bool isChecked(string Name) { foreach (Control mycontrol in panelCheckboxes.Controls) { //pull out the name CheckBox cb = (CheckBox)mycontrol; //make an enum. See if that is set. If so, mark it as checked if(cb.Text.ToLower() == Name.ToLower()) { return cb.Checked; } } return false; } private void UpdateChecked() { processing = true; DebugLevel toFind; int mycount = 0; string labelname = ""; NBSettings oursettings = NB.GetSettings(); if (MyMode == LBContents.puzzles) { foreach (Control mycontrol in panelCheckboxes.Controls) { //pull out the name CheckBox cb = (CheckBox)mycontrol; //make an enum. See if that is set. If so, mark it as checked if (cb.Checked) { mycount++; labelname = mycontrol.Text; } } if (mycount == 1) { //We only have one item checked. Store this value for later oursettings.ProcessingLevel = labelname; // oursettings.Save(); } } if (MyMode == LBContents.messages) { foreach (Control mycontrol in panelCheckboxes.Controls) { //pull out the name CheckBox cb = (CheckBox)mycontrol; //make an enum. See if that is set. If so, mark it as checked toFind = NB.ParseEnum(mycontrol.Text); if ((toFind & WhatToDisplay) == toFind) { cb.Checked = true; labelname = mycontrol.Text; mycount++; } else //If not, mark it as not checked. { cb.Checked = false; } } } processing=false; UpdateForm(); } private void btnAdd_Click(object sender, EventArgs e) { NBSettings oursettings = NB.GetSettings(); if (MyMode == LBContents.routes) { AddRoute(); } //In puzzle mode, this is the cancel button if(MyMode == LBContents.puzzles) { if (oursettings.AutoStartPuzzles != cbLoadPuzzlesAtStart.Checked) { oursettings.AutoStartPuzzles = cbLoadPuzzlesAtStart.Checked; // oursettings.Save(); } Close(); } //In regression, this is the test all button if (MyMode == LBContents.regressiontest) { //Loop through all the visible puzzles & process them in-order. RegressionTestAll(); UpdateForm(); } } private void RegressionTestAll() { PuzzleInfo pi; List Puzzles = NB.GetPuzzleNames(); NBSettings oursettings = NB.GetSettings(); if (Puzzles == null) return; List NeedingToDo = new List(); foreach (string OnePuzzle in Puzzles) { pi = NB.GetPuzzleInfoFromName(OnePuzzle); //shown_name = pi.PuzzleName; List tags = new List(pi.PuzzleTags); if (oursettings.HasReplay(OnePuzzle)) tags.Add(TestString); else continue; //Do not try it if there is no replay if (oursettings.HasPassed(OnePuzzle)) continue; //No need to test it again if it passed if (oursettings.HasFailed(OnePuzzle)) tags.Add(FailedString); if (!oursettings.HasFailed(OnePuzzle) && !oursettings.HasPassed(OnePuzzle) && oursettings.HasReplay(OnePuzzle)) tags.Add(Untested); foreach (string tag in tags) { if (isChecked(tag)) { NeedingToDo.Add(OnePuzzle); break; } } } //Now, loop through and do them int count = NeedingToDo.Count; foreach(string OnePuzzle in NeedingToDo) { //Visible = false; BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin != null) { //myWin.Activate(); FormColorForTesting(); myWin.replayNetwork(OnePuzzle, 1, count--); //Return back to the listbox window Visible = true; Activate(); FormColorContinuingLoop(); } } FormColorBackToNormal(); } private void AddRoute() { NB_IPAddress newip = new NB_IPAddress(NB.ZeroIPString, NB.ZeroIPString, NB.ZeroIPString); newip.Edit(myNetDevice, this, NB.Translate("LBW_AddRouteCreate")); myNetDevice.AddRoute(newip); UpdateForm(); } private void lbWindowData_DoubleClick(object sender, EventArgs e) { if (MyMode == LBContents.routes) { if (lbWindowData.SelectedIndex >= EditableCount) return; if (lbWindowData.SelectedIndex < 1) return; //we always subtract 1 since we have added one line of comment to the list myNetDevice.EditRoute(lbWindowData.SelectedIndex - 1, this); } if(MyMode == LBContents.dhcp) { //We always add one since we are skipping the loopback device myNetDevice.EditDHCP(lbWindowData.SelectedIndex + 1, this); } if (MyMode == LBContents.puzzles || MyMode == LBContents.regressiontest) { //Just like pressing the OK button. We load the map / process regression btnOK_Click(sender, e); } UpdateForm(); } private void lbWindowData_Edit_Click(object sender, EventArgs e) { lbWindowData_DoubleClick(sender, e); } private void lbWindowData_Delete_Click(object sender, EventArgs e) { if (MyMode == LBContents.routes) { if (lbWindowData.SelectedIndex >= EditableCount) return; if (lbWindowData.SelectedIndex < 1) return; //we always subtract 1 since we have added one line of comment to the list myNetDevice.DeleteRoute(lbWindowData.SelectedIndex - 1); } UpdateForm(); } private void lbWindowData_RightMouseUp(object sender, MouseEventArgs e) { int index=0; if(MyMode == LBContents.routes) { if (lbWindowData.ContextMenuStrip == null) { lbWindowData.ContextMenuStrip = new ContextMenuStrip(); } lbWindowData.ContextMenuStrip.Items.Clear(); lbWindowData.ContextMenuStrip.Items.Add(NB.Translate("_Edit")); lbWindowData.ContextMenuStrip.Items[index++].Click += lbWindowData_Edit_Click; lbWindowData.ContextMenuStrip.Items.Add(NB.Translate("_Delete")); lbWindowData.ContextMenuStrip.Items[index++].Click += lbWindowData_Delete_Click; } } private void lbWindowData_MouseUp(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { lbWindowData_RightMouseUp(sender, e); return; } else { if(MyMode == LBContents.puzzles) { if ((Form.ModifierKeys & Keys.Control) == Keys.Control && (Form.ModifierKeys & Keys.Alt) == Keys.Alt) { //We are control + alt clicking on something if (lbWindowData.SelectedItem != null) { string TheName = lbWindowData.SelectedItem.ToString(); TheName = Regex.Replace(TheName, @"^\* ", ""); //If the puzzle is solved, mark it as unsolved. //If it is unsolved, mark it as solved. NBSettings oursettings = NB.GetSettings(); if(oursettings != null) { if (oursettings.ScoreList.Contains(TheName)) { oursettings.ScoreList.Remove(TheName); } else oursettings.ScoreList.Add(TheName); } } } UpdateForm(); } if (MyMode == LBContents.regressiontest) UpdateForm(); } } private void btnReset_Click(object sender, EventArgs e) { if (MyMode == LBContents.regressiontest) { //In regressiontest mode, this is the cancel. ClosingRegression = true; Close(); return; } else { DialogResult answer = MessageBox.Show(NB.Translate("LBW_btnResetYouSure"), NB.Translate("LBW_btnResetForget"), MessageBoxButtons.YesNo); if (answer == System.Windows.Forms.DialogResult.Yes) { NBSettings oursettings = NB.GetSettings(); oursettings.ScoreList.Clear(); UpdateForm(); } } } private void tbSearchBox_TextChanged(object sender, EventArgs e) { //If there are more than 2 characters, then we start to see if we can filter it if (tbSearchBox.Text.Length > 2) { //Now we filter the results FilterString = tbSearchBox.Text; UpdateForm(); } else { FilterString = ""; UpdateForm(); } } } }