Moses Aprico
Moses Aprico

Reputation: 2121

User control binding is not properly working

I kinda stuck on data-binding here. So, let's say I have a following Class :

Student.cs

public class Student : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;       

    public string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; NotifyPropertyChanged("Name");
    }

    public bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set { _isSelected = value; NotifyPropertyChanged("IsSelected");
    }

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

Then, I have a UserControl to visualize the class, with the following ViewModel :

StudentVisualizerVM.cs

public class StudentVisualizerVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Student _student;
    public Student Student
    {
        get { return _student; }
        set { _student = value ; NotifyPropertyChanged("Student"); }
    }

    public StudentVisualizerVM()
    {
        Student = new Student();
    }

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

And then, I want to use the UserControl in my MainWindow.

MainWindow.Xaml

<ItemsControl Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Student}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <c:StudentVisualizer/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

And finally this is my MainWindow ViewModel look like :

MainWindowVM.cs

public class MainWindowVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Student _student;
    public Student Student
    {
        get { return _student; }
        set { _student = value ; NotifyPropertyChanged("Student"); }
    }

    public MainWindowVM()
    {
        Student = new Student();
    }

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

The problem is that the User Control didn't shows up on MainWindow even though I had initialize the Student Property in MainWindow. Why? Isn't MVVM User Control automatically populate its ViewModel? Or maybe it's StudentVisualizerVM that I need to store in MainWindowVM, instead of the Student itself?

Note That (Updated) :

  1. Above code is not the real one, it's just to simplify my project into the main problem.
  2. Assume each XAML's DataContext has been attached correctly from the XAML.CS.
  3. Why I need to do this? Because I need to detect if the window has been clicked outside the StudentVisualizer then IsSelected is set to false. (This property used for certain Command which need the Student to be selected.) - Something like Select-Deselect-esque actio.

Upvotes: 0

Views: 56

Answers (1)

franssu
franssu

Reputation: 2430

ItemsControl is for displaying a collection of items, therefore ItemsControl.ItemsSource has to bind to an IEnumerable property, while you just bind to a single element.

You want something like :

ItemsSource="{Binding StudentCollection}"

public IEnumerable<Student> StudentCollection 
{
    get { return new List<Student> { Student }; }
}

Now, should you really use an ItemsControl to display just one item.. that's another question and the answer would be : no.

Upvotes: 1

Related Questions