0

I am trying to programatically add items to a ListView in WPF. I have done a lot of reading (including some questions here) and thought I was doing it correctly but the items aren't showing up. As I understand it I create the ListViewe and bind it to a data source, in this case an ObservableCollection. I have verified the ObservableCollection is getting items added to it, but they aren't getting displayed on the ListView. If it matters, the ListView is already instantiated by the time I run the LINQ query and attempt to add items to it.

Here is the XAML that defines the list view:

<TabPanel Name="ResultsTab" Height="200" Width ="500" DockPanel.Dock="Top" HorizontalAlignment="Left">
        <TabItem Name="Default_Tab" Header="Default">
            <ListView Name="DefaultListView" ItemsSource="Binding FCPortCollection">
                <ListView.View>
                    <GridView x:Name="DefaultGridView">
                        <GridViewColumn Width="Auto" Header="FC Port" DisplayMemberBinding="{Binding Path=FCPort}" />
                        <GridViewColumn Width="Auto" Header="WWPN" DisplayMemberBinding="{Binding Path=WWPN}"/>
                        <GridViewColumn Width="Auto" Header="FCID" DisplayMemberBinding="{Binding Path=FCID}" />
                        <GridViewColumn Width="Auto" Header="SwitchName" DisplayMemberBinding="{Binding Path=SwitchName}">
                        </GridViewColumn>                 
                    </GridView>   
                </ListView.View>     
            </ListView>
        </TabItem>

And here is the code that is supposed to load it.

public class PortResult
{
    public string SwitchName;
    public string FCPort;
    public string FCID;
    public string WWPN;

    public PortResult(string name, FCPort port)
    {
        SwitchName = name;
        FCPort = String.Format("fc{0}/{1}", port.SlotNum, port.PortNum);
        WWPN = port.WWPNList[0].WWPNValue;
        FCID = port.WWPNList[0].FCIDValue;

    }
}

ObservableCollection<PortResult> FCPortCollection = new ObservableCollection<PortResult>();

// results is an IEnumerable collection of FCPort result from a LINQ query that has been turned into a Dictionary
foreach (KeyValuePair<string, List<FCPort>> resultspair in results)
      {
            foreach (FCPort port in resultspair.Value)
            {    
                // create a new PortResult and add it to the ObservableCollection
                PortResult pr = new PortResult(resultspair.Key, port);
                FCPortCollection.Add(pr);
            }
        }
2
  • Know how to debug bindings? Commented Feb 21, 2012 at 18:27
  • You're welcome, those basics are important :) Commented Feb 21, 2012 at 19:23

2 Answers 2

3

There are several problems in the code you posted:

  1. The binding syntax for your ItemsSource is missing the {} braces - it needs to be ItemsSource="{Binding FCPortCollection}"
  2. You can only bind to properties, however you only expose fields in your PortResult class. Change those fields to be properties.

Also make sure the DataContext of the ListView is set to the object which contains the FCPortCollection. Also make sure the collection is a property of the object and not a field (same reason as point 2. above).

Sign up to request clarification or add additional context in comments.

5 Comments

I fixed the ItemsSource issue and changed the the PortResult Class to have public properties backed by private fields. I also added this: DefaultListView.DataContext = FCPortCollection; to the code. FCPortCollection is a class variable of type ObserveableCollection for the form that contains the ListView Stll no joy.
@DavidGreen: If you set the DataContext of the ListView directly to the collection then you need to use ItemsSource={Binding} (no path specified). The binding is always relative to the data context. If if you say {Binding Foo} then the binding engine will look for a property called Foo in the data context object.
Thanks Chris. I fixed some issues and the DataContext is now showing a list of items, as is the ItemsSource in the debugger WatchWindow. However, the ListView is still not displaying the items. I verified that the names of the properties in the PortResult Class are the same names as the bindings for the GridViewColumns
Oh is it an issue that I am doing all of this after InitializeComponent() is called for the window that contains the ListView? Most of the examples I see have all this in the constructor for the form that contains the ListView, then InitializeComponent() is called. Eventually I want to be able to add tabs to the TabCollection with other listviews that have different search results
thanks for all the help. After some more work in the debugger, I got rid of the Tab Control. Now the list works and I can see it. I'd like to figure out why I can't see the list inside the tab control. My idea is to be able to run different queries on the data with each one in its own tab.
2

This:

ItemsSource="Binding FCPortCollection"

Is not a binding, you forgot the braces {} and hence assigned a char[] as ItemsSource instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.