WPF DataGrid / ListView bind to array mvvm

2019-02-27 07:54发布

问题:

Let's assume that you have

  • an array of N integers
  • an integer value representing number of rows

in the model. The integer is bound to a ComboBox in the view.

Q1) How do you bind the array (or individual items of the array) to a DataGrid or a ListView control so that:

  • when you change the ComboBox value, only that many rows are visible/generated in the DataGrid or ListView
  • Individual rows of the DataGrid or ListView contain TextBoxes (or similar) that allow to edit the corresponding value in the array. The binding must be two-way.

I.e. If i select 5 in the ComboBox, only 5 rows are visible containing 5 TextBoxes that are each bound to the first 5 items of the array.

Q2) How would you provide another column (only text information) to the DataGrid / ListView so that:

  • First row would always read 0. Each subsequent row would read: 'previous row' + '360 divided by ComboBox selected value' (providing that it would be limited to even numbers for simplicity).

Any help or suggestions are really appreciated.
Thank you.

EDIT (22.11.2013):
Following suggestions of Sheridan I am linking this question to my other question that has more information (and context) to this question.

Originally I opened this question because I thought that a question stripped down of any context just to the bare mechanics would get better understanding and better chance to being answered.
I stand corrected.

回答1:

Ok, so if you're going to do this properly, you'll first need to create a data type/model class to hold your data. It should implement the INotifyPropertyChanged interface correctly and contain a property for each column that you want to display in the DataGrid including an extra one for your 'Q2' requirement.

Next, you want to add two properties of type ObservableCollection<YourDataType> into your code behind/view model. The first will hold the whole collection and the second will display just the number of rows that you want. You'll also need an integer property to Bind to the selected item of the ComboBox:

<DataGrid ItemsSource="{Binding FilteredItems}" ... />
...
<ComboBox ItemsSource="{Binding Numbers}" SelectedItem="{Binding SelectedItem}" />

Now, whenever the SelectedItem property changes in the view model, you just need to update the number of rows of items in the FilteredItems property:

public int SelectedItem
{
    get { return selectedItem; }
    set
    {
        selectedItem = value;
        NotifyPropertyChanged("SelectedItem");
        UpdateFilteredItems();
    }
}
...
private void UpdateFilteredItems()
{
    FilteredItems = 
        new ObservableCollection<YourDataType>(Items.Take(SelectedItem));
}

In the UpdateFilteredItems method, we simply take the relevant number of items from the whole Items collection based on the SelectedItem value. As the FilteredItems collection is bound to the DataGrid.ItemsSource, the UI will automatically update.