Question

Currently my model has ten properties which for our purposes here I'll call AnnualizedRate1, AnnualizedRate2, ..., AnnualizedRate10 which are revealed to views in the view model via ten properties Rate1, Rate2, ..., Rate10. One of my views shows these values in a DataGrid. This is awfully repetitious and a pain to adapt to changing requirements. There has to be a better way than the following.

Model (MyModel):

public decimal AnnualizedRate1 { get { return this.AnnualizedRate(1); } }
public decimal AnnualizedRate2 { get { return this.AnnualizedRate(2); } }
...
public decimal AnnualizedRate10 { get { return this.AnnualizedRate(10); } }

where MyModel.AnnualizedRate is

public decimal AnnualizedRate(int i);

View Model (MyViewModel):

public decimal Rate1 { get { return myModel.AnnualizedRate1; } }
public decimal Rate2 { get { return myModel.AnnualizedRate2; } }
...
public decimal Rate10 { get { return myModel.AnnualizedRate10; } }

View (MyView):

xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
...
    <dg:DataGrid>
        <dg:DataGrid.Columns>
            <dg:DataGridTextColumn
                Header="Rate1" 
                Binding="{Binding Rate1, StringFormat=P}"
                IsReadOnly="True"/>
            <dg:DataGridTextColumn
                Header="Rate2" 
                Binding="{Binding Rate2, StringFormat=P}"
                IsReadOnly="True"/>
            ...
            <dg:DataGridTextColumn
                Header="Rate10" 
                Binding="{Binding Rate10, StringFormat=P}"
                IsReadOnly="True"/>
        </dg:DataGrid.Columns>
    </dg:DataGrid>

Does anyone have any ideas?

Was it helpful?

Solution

I would use and ObservableCollection to store the data and bind the grid to.

OTHER TIPS

Here is the code to do what RB Davidson said to do. When you find that this does what you wanted, please give him credit. His answer is correct.

In your ViewModel:

public class AnnualizedRateViewModel
{
     public string Name { get; set; }
     public decimal Rate { get; set; }
}

public MyViewModel : INotifyPropertyChanged
{

public MyViewModel()
{
     AnnualizedRates = new ObservableCollection<AnnualizedRateViewModel>();
     //I'd recommend your model having a GetAllRates() function rather than this,
     //but for demo purposes, this works
     for(int i = 1; i <= 10; i++)
     {
          AnnualizedRates.Add(new AnnualizedRateViewModel()
          {
               Name = string.Format("Rate {0}", i),
               Rate = MyModel.AnnualizedRate(i)
          });
     }
}

private ObservableCollection<int> _annualizedRates;
public ObservableCollection<int> AnnualizedRates
{
     get { return _annualizedRates; }
     set
     {
          _annualizedRates = value;
          //Raise OnNotifyPropertyChanged event from your
          //implementation of INotifyPropertyChanged in your viewmodel
          //the full implementation of this is outside the scope of this demo
     }
}

}

From there you'd actually use databinding to create the columns in your view. You'd bind to this collection of AnnualizedRates. Since the WPF Toolkit doesn't make this easy, you'll have to write a value converter to convert the ObservableCollection<AnnualizedRateViewModel> to an ObservableCollection<DataGridColumn>.

<dg:DataGrid AutoGenerateColumns="false" Columns="{Binding AnnualizedRates, ValueConverter={StaticResource AnnualizedRatesToDataGridColumnCollectionConverter}}">
</dg:DataGrid>

The thing you should learn here is when you are thinking to yourself "repetition", try and instead think "collection".

Good luck... and again, credit RB Davidson.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top