7

I have a observable collection of type Project, that I want to be displayed in a ListView but nothing is added to my ListView which I really dont understand

My MainWindow.xaml

            <ListView Name="ListViewProjects" Grid.Column="0" Grid.RowSpan="3" SelectionChanged="ListViewProjectsSelectionChanged" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" MinWidth="100">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock Text="{Binding Path=ProjectID}"/>
                        <TextBlock Text="{Binding Path=ProjectName}"/>
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

My MainWindow.cs

    public partial class MainWindow : Window
{
    ObservableCollection<Project> Projects = new ObservableCollection<Project>();
    ObservableCollection<Employee> Employees = new ObservableCollection<Employee>();

    public MainWindow()
    {
        InitializeComponent();

        DataContext = Projects;

        Project pro1 = new Project(1, "Swordfish");
        Projects.Add(pro1);
        Employee empMads = new Employee("Mads", 1);
        Employee empBrian = new Employee("Brian", 2);
        Employees.Add(empMads);
        Employees.Add(empBrian);
    }

    private void ListViewProjectsSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    }
}

and my Project.cs which is the class file

[Serializable]
class Project : INotifyPropertyChanged
{
    public Project(int id, string name)
    {
        ID = id;
        Name = name;
    }

    private int id;
    public int ID
    {
        get { return id; }
        set
        {
            id = value;
            NotifyPropertyChanged("ProjectID");
        }
    }

    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            NotifyPropertyChanged("ProjectName");
        }
    }

    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

But nothing is added to my list I cant see what I am missing for it to work.

I have it as a observablecollection I do DataContext = the collection And I do binding in the xaml file

Edit codepart 1:

        public ObservableCollection<Project> Projects { get; set; }
    public ObservableCollection<Employee> Employees { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        Projects = new ObservableCollection<Project>();
        Employees = new ObservableCollection<Employee>();

        DataContext = Projects;
1
  • Think you could post how you setup your DataContext? Commented Jan 13, 2011 at 14:04

4 Answers 4

4

It's because you use binding path like ProjectID while your Project class has property ID. The same goes for ProjectName and Name properties.

E: When you have problems with binding it's very useful to look through Output tab in visual studio's debug mode to see what errors were returned from databinding engine. Those exceptions are normally not returned to user, but you can inspect them there.

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

6 Comments

That worked, but I cant see anything in my output or errorlist when its written in the wrong way. Btw is it possible to have a combobox I have in the same xaml document databind to another list?
System.Windows.Data Error: 40 : BindingExpression path error: 'ProjectID' property not found on 'object' ''Project' (HashCode=41717140)'. BindingExpression:Path=ProjectID; DataItem='Project' (HashCode=41717140); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') - This is the message I found in my output window when I've first started your code. And yes, it's possible to change data source in runtime (I suppose this is what you're asking for), but here i don't have enough space. I'm sure you can find on web how to do this.
Usedful because I didn't know that VS would output the databinding errors. That's gonna reduce my XAML/WPF debugging time a lot, cheers!
I dont see those errors anywhere, not sure why mine dont output that
On Output window in dropdown "Show output from:" what do you have selected? There should be debug. If it's set to Build, than select debug. Hope it'll work.
|
3

As pointed out, there are a few problems here. One of the "gotchas" that get you as a new WPF developer is that you can't use member variables, you have to use public properties:

public ObservableCollection<Project> Projects { get; set; }
public ObservableCollection<Employee> Employees { get; set; }

These, of course, need to be initialized in your constructor.

Once you do that, you need to make sure the properties of the collection match what you're binding to on the ListView.

2 Comments

Well, maybe I'm wrong, but you can use private field as datacontext (this is what Mech0z is doing) and everything works just fine.
Thank you, once I converted my public fields to properties the binding started working.
1

By default your member variables are going to be private. If what you have posted here is your actual code, then the XAML has no way of accessing it. Makes those properties public:

public ObservableCollection<Project> Projects = new ObservableCollection<Project>();
public ObservableCollection<Employee> Employees = new ObservableCollection<Employee>();

9 Comments

Those are public fields, not sure but i don't think that will work either.
Instance fields are private by default. If you look at his code, he omits any scope modifier, which makes them private.
I mean what you wrote are public fields, bindings need public properties as far as i know.
It doesn't matter anyway, as you can set private field as datacontext as well. Or at least it's working just fine on my VS2010 ;)
Of course that is possible, you'd just have two bindings with different Paths (which is another reason why you should not set the DataContext of the window to something as specific as one of its properties, rather set it to itself via "DataContext = this;", then the bindings are {Binding Projects) and {Binding Employees})
|
0

1.Your list needs to be a public property (Edit: unless you set the DataContext like you did...) (public ObservableCollection<Project> Projects {get;})

2.Your notification should be the same as the actual property name:

private int id;
public int ID
{
    get { return id; }
    set
    {
        id = value;
        NotifyPropertyChanged("ID");
    }
}

3.The binding needs to be that way as well:

<TextBlock Text="{Binding Path=ID}"/>

I think...

2 Comments

If I make them propertys as you can see in my "Code edit 1" I added to the primary question and comment out the Datacontext = Projects then nothing is added, then I need to change my binding in my my listview, but what should that be?
If your window is named MyWindow in the Xaml your binding could be done with ItemsSource="{Binding ElementName=MyWindow, Path=Projects}"

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.