Vlad
Vlad

Reputation: 2773

Implement INotifyPropertyChanged on a list of objects?

Hmm, not sure if I chose the right approach. I have a grid of components. In the first column there are DatePickers. In the second column there are combo-boxes. In the last column there are text-boxes. The grid has 15 rows. I named them by their column and row number as you would number cells in a grid. So dp1_1 for DatePicker are position (1,1), dp2_1 for position (2,1). cb1_1 for ComboBox are position (1,1), cb2_1 for ComboBox position (2,1).

I keep my date pickers data, combo-boxes data, text-boxes data in an ordinary list for easy access/reference, like so:

public int numOfRows = 15;
private List<DateTime> _MyDateTimeList = new List<DateTime>();

public List<DateTime> MyDateTimeList
{
    get { return _MyDateTimeList; }
    set {
        DateTime pomDatumObjava;

        _MyDateTimeList = value;

        for (int i = 0; i < numOfRows; i += 1)
        {
            pomDatumObjava = new DateTime();
            // code for accessing/enabling/disabling the appropriate date picker, which doesn't work since I don't know how to send the window reference where my date pickers reside
            // pomDatumObjava = Utils.enableDisableDatePicker(null, Constants.DP_LABEL + stringIndex, true, 1).SelectedDate.Value;
            _MyDateTimeList.Add(pomDatumObjava);
        }

        OnPropertyChanged("MyDateTimeList");
    }
}

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string name)
{
    Console.WriteLine("OnPropertyChanged -> " + name);
    PropertyChangedEventHandler handler = PropertyChanged;

    if (handler != null)
    {
        Console.WriteLine("handler != null -> " + name);
        handler(this, new PropertyChangedEventArgs(name));
    }
}

public static DatePicker enableDisableDatePicker(System.Windows.Window myWindow, string name, bool enableDisable, double op)
{
    DatePicker dp = (DatePicker)myWindow.FindName(name);

    if (!enableDisable)
    {
        dp.SelectedDate = null;
    }

    dp.IsEnabled = enableDisable;
    dp.Opacity = op;

    return dp;
}

How do I access my components in the window and reference them appropriately so that each time I change a value in certain DatePicker, I detect the change in the list?

You can find the Utils function in comments line. Where it says null, there should be the window objects where my components are placed.

Or, is this the right approach?

I will have lot of components(15x3 = 45 x code for OnPropertyChanged), so the MVVM file will be quite large to set OnPropertyChanged() for all of them.

Upvotes: 0

Views: 1945

Answers (1)

Robin Bennett
Robin Bennett

Reputation: 3231

As ASh says, you need an ObservableCollection of objects, one for each row. ObservableCollections automatically update their bound controls when you add or remove objects, and pass on events when the objects change. These objects would presumably have three properties (for the datepicker, combobox and text box) that have OnPropertyChanged().

Then bind the ObservableCollection to the ItemSource of your grid, and the three controls to the three properties of an item.

For MVVM, you shouldn't ever need to reference a control in the View. Instead the view should reflect the state of the ViewModel. If you want to disable a datepicker, it's Enabled property should be bound to some thing that raises OnPropertyChanged().

If you post your view, we can suggest how to do this.

Upvotes: 1

Related Questions