Navigating to selected ListViewItem on doubleclick

463 Views Asked by At

I'm making a simple browser in Visual Studio.
To be able to save and delete bookmarks, I'm using these codes:

When the frmFavorites is opened, it'll read an xml-file named Favorites.xml

private void frmFavorites_Load(object sender, EventArgs e) {
        System.Xml.XmlDocument loadDoc = new System.Xml.XmlDocument();
        loadDoc.Load(Application.StartupPath + "\\Favorites.xml");

        foreach (System.Xml.XmlNode favNode in loadDoc.SelectNodes("/Favorites/Item")) {
            listViewFavs.Items.Add(favNode.Attributes["url"].InnerText);
        }
    }

When the form is closed again, it'll overwrite the xml-file and save all remaining items in the xml-file

private void frmFavorites_FormClosing(object sender, FormClosingEventArgs e) {
        System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(Application.StartupPath + "\\Favorites.xml", null);

        writer.WriteStartElement("Favorites");
        for (int i = 0 ; i < listViewFavs.Items.Count ; i++) {
            writer.WriteStartElement("Item");
            writer.WriteAttributeString("url", listViewFavs.Items[i].Text);
            writer.WriteEndElement();
        }
        writer.WriteEndElement();
        writer.Close();
    }

To add and delete a bookmark, I'm using this code:

private void btnAddFav_Click(object sender, EventArgs e) {
        ListViewItem item = new ListViewItem(txtURL.Text);
        listViewFavs.Items.Add(txtURL.Text);
    }

    private void btnDelFav_Click(object sender, EventArgs e) {
        try {
            listViewFavs.Items.RemoveAt(listViewFavs.SelectedIndices[0]);
        }
        catch {
            MessageBox.Show("Je moet een item selecteren", "Geen item geselecteerd", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }

Now, my problem:
I'd like to give my users the ability to double click on an item so they can navigate to their saved fav. At least, that's what SHOULD happen.
For so far, I've tried some codes and ended up with this:

private void listViewFavs_DoubleClick(object sender, EventArgs e) {
        try {
            FrmMain Main = new FrmMain();
            Main.navigate(listViewFavs.SelectedItems[0].Text);
        }
        catch {
            MessageBox.Show("Je moet een item selecteren", "Geen item geselecteerd", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }

frmMain is my browser and navigate is a public method that I use to check the URL's and to navigate.

To navigate, I use this code:

public void navigate(String URL) {
        if (String.IsNullOrEmpty(URL) || URL.Equals("about:blank")) {
            GetActiveBrowser().DocumentText = Properties.Resources.FirstTime; // this is a HTML-doc you also see when you open the browser for the 1st time
            txtURL.Text = "about:blank";
            return;
        } else if (!URL.StartsWith("http://") && !URL.StartsWith("https://") && !URL.StartsWith("file://") && !URL.StartsWith("ftp://"))
            URL = "http://" + URL;
        try {
            GetActiveTab().Text = "... Loading ...";
            this.Icon = Properties.Resources.loading1;
            GetActiveBrowser().Navigate(new Uri(URL));
        }
        catch (System.UriFormatException) {
            MessageBox.Show("'" + URL + "' is geen geldige URL", "Ongeldige URL", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    } // go to URL

As you can see, I use a GetActiveTab() and GetActiveBrowser:

private WebBrowser GetActiveBrowser() {
        return (WebBrowser)tabs.SelectedTab.Controls[0];
    }

private TabPage GetActiveTab() {
        return tabs.SelectedTab;
    }

What actually happens:
I double-click on the item
Nothing happens -.- No navigation, no error, no nothing

Does anyone have an idea to fix this problem?
I appreciate any help given.

1

There are 1 best solutions below

5
On

It looks like you're removing the item from the list, then trying to access that item.

Here you remove the item:

listViewFavs.Items.RemoveAt(listViewFavs.SelectedIndices[0]); 

then right here you are trying to access the selected items, but it's not there, you just removed it:

Main.navigate(listViewFavs.SelectedItems[0].Text); 

Try not calling RemoveAt, you don't want to remove it anyway right? If the goal is just to use that selected item to navigate on the parent form, then removing it from the list of bookmarks is counter intuitive.

Edit:

To Debug navigate, you'll need to step into that call (set a breakpoint at the first line) and verify that URL is getting a value. Use Step-Over (usually F10), to walk through the function and verify it takes the code path you're expecting it to.

Also, and perhaps more importantly, it seems that you are creating a new FrmMain but not showing it. Then it goes out of scope, since it is defined in that method, and the GC then sweeps it up.

You should being doing one of two things here:

1) Using an existing instance of FrmMain, which is probably the case, since I'm assuming someone launches frmFavorites from FrmMain and then is double clicking to navigate back in the already open window.

2) Or calling Main.Show() to make the new form visible so it will live after the method it was defined in has returned.

If the FrmMain instance may or may not be already in existence when the users clicks on a favorite, you could use a lazy loaded static instance that you refer to anywhere you need access to the main form. So in the double click handler:

FrmMain main = FrmMain.Instance;
main.Show();
main.navigate(listViewFavs.SelectedItems[0].Text);

then in FrmMain:

static FrmMain _instance;
public static FrmMain Instance 
{
   if (_instance==null)
       _instance = new FrmMain();

   return _instance;
}