John P.
John P.

Reputation: 1249

C# WPF ListView not deleting items properly

I have a ListView which looks like this;

<Window x:Class="WPF_Viewer.URLLinks"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WPF_Viewer"
    mc:Ignorable="d"
    Title="URLLinks" Height="461.215" Width="606.542" WindowStartupLocation="CenterScreen">
<Grid>
    <ListView x:Name="proxyListView" Loaded="proxyListView_Loaded">
        <ListView.ContextMenu>
            <ContextMenu Name="contextMenu1">
                <MenuItem Name="item1" Header="Delete" Click="item1_Click"/>
            </ContextMenu>
        </ListView.ContextMenu>
    </ListView>
</Grid>
</Window>

I am trying to add a ContextMenu to delete SelectedItem This is the code behind;

public partial class URLLinks : Window
{
    public URLLinks()
    {
        InitializeComponent();
    }

    private void proxyListView_Loaded(object sender, RoutedEventArgs e)
    {
        proxyListView.ItemsSource = GlobalVars.URLLinks;
    }

    private void item1_Click(object sender, RoutedEventArgs e)
    {
        GlobalVars.URLLinks.RemoveAt(proxyListView.SelectedIndex);
        ICollectionView view = CollectionViewSource.GetDefaultView(proxyListView.ItemsSource);
        //view.Refresh();
    }
}

Any ideas?

EDIT: this is the variable and how it is set

public static async void GetLink(string url)
    {
        try
        {
            string sURL = url;
            Uri uri = new Uri(sURL);
            string host = uri.Host;
            using (HttpClient clientduplicate = new HttpClient())
            {
                clientduplicate.DefaultRequestHeaders.Add("User-Agent",
                    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident / 6.0)");
                using (HttpResponseMessage responseduplicate = await clientduplicate.GetAsync(sURL))
                {
                    using (HttpContent contentduplicate = responseduplicate.Content)
                    {
                        try
                        {
                            string resultduplicate = await contentduplicate.ReadAsStringAsync();
                            var websiteduplicate = new HtmlAgilityPack.HtmlDocument();
                            websiteduplicate.LoadHtml(resultduplicate);
                            List<string> ListItems = new List<string>();
                            Settings.Default.Reload();
                            int maxLinks = Convert.ToInt32(Math.Round(Convert.ToDouble(Settings.Default["subLinksValue"]) * 10));

                            foreach (HtmlNode links in websiteduplicate.DocumentNode.SelectNodes("//a[@href]"))
                            {
                                HtmlAttribute att = links.Attributes["href"];
                                foreach (var link in att.Value.Split(' '))
                                {
                                    if (ListItems.Count >= maxLinks)
                                    {
                                        GlobalVars.URLLinks = ListItems;
                                        //File.WriteAllLines(AppDomain.CurrentDomain.BaseDirectory + @"\links.txt", ListItems.ToArray());
                                        return;
                                    }
                                    if (link.StartsWith("http") && link.Contains(host) && CheckURLValid(link))
                                    {
                                        ListItems.Add(link);
                                    }
                                }
                            }
                            GlobalVars.URLLinks = ListItems;
                            //File.WriteAllLines(AppDomain.CurrentDomain.BaseDirectory + @"\links.txt", ListItems.ToArray());
                            //return ListItems;
                        }
                        catch (Exception ex1)
                        {
                            Console.WriteLine("Error getting links");
                            //return null;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show("Error, url not formatted correctly. Try coping your url from your browser");
        }
    }

Upvotes: 0

Views: 751

Answers (3)

Brandon
Brandon

Reputation: 3266

The only thing I had to do in order to get this to work is change your collection from List<string> to ObservableCollection<string>.

Once you do that, you don't need to reset the items on the list view.

static ObservableCollection<string> items = new ObservableCollection<string>() { "Item 1", "Item 2" };

private void proxyListView_Loaded(object sender, RoutedEventArgs e)
{
    proxyListView.ItemsSource = items;
}

private void item1_Click(object sender, RoutedEventArgs e)
{
    items.RemoveAt(proxyListView.SelectedIndex);
} 

Upvotes: 2

Peregrine
Peregrine

Reputation: 4546

Even if you're not going to go the full MVVM route, at least use an ObservableCollection of items and assign your ListView's ItemSource to that. This will automatically update the control when an item is removed or added.

Trying to perform business logic operations on a U.I. control will soon degenerate into a big ball of spaghetti.

Upvotes: 2

mm8
mm8

Reputation: 169190

If GlobalVars.URLLinks returns an ObservableCollection<T> or any other custom type that implements the INotifyCollectionChanged interface, this will work:

private void item1_Click(object sender, RoutedEventArgs e)
{
    var ic = proxyListView.ItemsSource as IList<string>;
    ic.RemoveAt(proxyListView.SelectedIndex);
}

But if the source collection doesn't raise change notifications when items are removed (a List<T> doesn't), you will have to re-set the ItemsSource property after you have removed an item to refresh the ListView:

private void item1_Click(object sender, RoutedEventArgs e)
{
    GlobalVars.URLLinks.RemoveAt(proxyListView.SelectedIndex);
    proxyListView.ItemsSource = GlobalVars.URLLinks;
}

Upvotes: 2

Related Questions