0

I have list of IP and servers in my host file, which I am viewing in ListView control for better UI and I wrote a code snippet which will ping each server and if its pass it highlights the particular as green and if fails it highlight it with Red. Now whenever counter reaches 15 or 15+ it throws exeception, can any body help me on this.

There are around 42 server list which will appear we we scroll the listview control.

I guess at once only less than >15 items are displayed in screen may be this could be the reason.

    private void pingAllIPinOneShot()
        {
            try
            {
                PingTest C_ping = new PingTest();
                int i = 0;
                string[] lines = File.ReadAllLines(_hostFilePath, Encoding.UTF8);
                foreach (var line in lines)
                {
                    i = i + 1;
                    if (line != " ")
                    {
                        string strResult = Regex.Replace(line, @"\s+", " ");
                        if (!strResult.Contains("#"))
                        {
                            string IPval = Before(strResult, " "); // to get value before sapce (i.e IP)
                            string serverVal = After(strResult, " ");// to get value before sapce (i.e server address)
                            string stat = PingAddr.GetPingAddr(serverVal);
                            if (stat != "Fail")
                            {
                                ListViewItem row = DataList.ItemContainerGenerator.ContainerFromIndex(i-1) as ListViewItem;
                                row.Background = Brushes.GreenYellow; //code fails here if 16th counter hit here
                            }
                            else
                            {
                                ListViewItem row = DataList.ItemContainerGenerator.ContainerFromIndex(i-1) as ListViewItem;
                                row.Background = Brushes.Red; //code fails here if 16th counter hit here
                            }
                            Thread.Sleep(1500); // delay to slow down the spreed
                        }
                    }
                }
            }
            catch(Exception EX)
            {
                MessageBox.Show(EX.Message);
            }
            }

see the snapshot here

Vivek Sharma
  • 29
  • 2
  • 12
  • I bet is has to do with recycling in WPF ListView control – paparazzo Mar 25 '18 at 10:27
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Richardissimo Mar 25 '18 at 10:27
  • What exception and what line? – paparazzo Mar 25 '18 at 10:31
  • `DataList.ItemContainerGenerator.ContainerFromIndex` you cannot get this unless the container is generated, which will happen if you actually view that listitem. A better way around all of this is to use DataBinding. Just bind a property to the Background of your listitem. – thunderbird Mar 25 '18 at 10:37
  • Can I any sample example which can solve my problem – Vivek Sharma Mar 25 '18 at 10:58
  • Or else other than ListView control, can any 1 help me with some other tool where I can highlight the corresponding servers Grren or Red based on status. Please provide me the working or set of example. – Vivek Sharma Mar 26 '18 at 13:22

2 Answers2

0

Here Finally I had a hack trick Instead of ListView control I replaced it with ListBox and now I am able to change the UI color of servers. Green for which all passed the Ping test and Red for Ping failure.

below is my code.

private void pingAllIPinOneShot()
    {
        int i = 0;
        try
        {

            PingTest C_ping = new PingTest();
            string[] lines = File.ReadAllLines(_hostFilePath, Encoding.UTF8);
            foreach (var line in lines)
            {
                i = i + 1;
                if (line != " " && line != "")
                {
                    string strResult = Regex.Replace(line, @"\s+", " ");
                    char isHostCommented = strResult[0];
                    if (isHostCommented != '#') // assuming # at begining as commented server
                    {
                        string IPval = Before(strResult, " ");
                        string serverVal = After(strResult, " ");
                        string stat = PingAddr.GetPingAddr(serverVal);
                        if (stat != "Fail")
                        {
                            Dispatcher.BeginInvoke(new Action(() =>
                            {
                                listBox1.Items.Remove(line);
                                listBox1.Items.Add(new ListBoxItem { Content = line, Background = Brushes.GreenYellow });
                            }), DispatcherPriority.Background);

                        }
                        else
                        {
                            Dispatcher.BeginInvoke(new Action(() =>
                            {
                                listBox1.Items.Remove(line);
                                listBox1.Items.Add(new ListBoxItem { Content = line, Background = Brushes.IndianRed });
                            }), DispatcherPriority.Background);
                        }
                        Thread.Sleep(800); // delay to slow down the spreed
                    }
                }
            }
            MessageBox.Show("Ping Test all Done");
        }
        catch (Exception EX)
        {
            MessageBox.Show("Failed on counter " + i + " " + EX.Message);
        }
    }

click here to see the image

Vivek Sharma
  • 29
  • 2
  • 12
-1

I can describe how I'd approach this. Which is MVVM and a bit like this sample: https://gallery.technet.microsoft.com/WPF-Dialler-simulator-d782db17

I'd have a viewmodel for the window datacontext (MainWindowViewmodel)and one representing a server (serverVM). Expose an observablecollection of serverVM from the MainWindowViewmodel as a public property and bind to the itemssource of a listview. A dispatcher timer would fire every 1500ms. In the event for that, iterate all the serverVM and call a public method on serverVM which pings. That then sets a public property which would be a solidcolorbrush ( like the phonebrush in that sample ). Depending on whether it pings or not, set the brush property to Brushes.Red or Brushes.Green. Then bind the background colour of the listviewitems.

<ListView>
    <ListView.Resources>
        <Style TargetType="{x:Type ListViewItem}">
               <Setter Property="Background" Value="{Binding YourBrush}" />
        </Style>
    </ListView.Resources>
Andy
  • 11,864
  • 2
  • 17
  • 20