Kiang Teng
Kiang Teng

Reputation: 1705

Whether to include view specific information in model

I currently have a class containing the following properties

public class Chromosome
{
    public int Length
    {
        get;
        set;
    }

    public int Number
    {
        get;
        set;
    }

    public Chromosome(int _length, int _number)
    {
        Length = _length;
        Number = _number;
    }
}

I have a list box data binded to my view model. The items source is data binded to a Observable of Chromosome objects ChromosomeList.

<Grid>
        <ListBox Style="{StaticResource ListBoxStyle}"  
                 ItemsSource="{Binding Path=ChromosomeList}"
                 ItemTemplate="{StaticResource ChromosomeDataTemplate}">
        </ListBox>
    </Grid>

The ItemTemplate for the list box items is ChromosomeDataTemplate and is shown below.

<DataTemplate x:Key="ChromosomeDataTemplate">
    <Border>
        <Grid Height="10">
            <TextBlock VerticalAlignment="Bottom" 
                       Text="{Binding Number}">
            </TextBlock>
        </Grid>
    </Border>

In this case, I want the Height property of the grid to be data binded to the Length property of the chromosome. However, as the Length is extremely large, I need it to be a small percentage of the actual value. I could do this by:

However, I feel that this does not follow the MVVM Pattern. Is there any way to modify the Length value when data binding it?

Upvotes: 0

Views: 87

Answers (3)

Jon
Jon

Reputation: 437664

Chromosome is your Model. Your XAML code resides in your View. The hypothetical "modified-length" value should reside in your ViewModel.

You are correct in saying that making a new property for the modified height is not MVVM (and is a very bad idea generally, of course).

For a better approach, you would normally put the modified-length property in the ViewModel. However your problem is now that your ViewModel has an ObservableCollection<Chromosome> and therefore cannot provide a simple modified-length property for each one of the Chromosome instances.

Therefore, you have two choices:

  1. Implement a ValueConverter that translates the original Length to an appopriate Grid.Height. This could be either in your ViewModel or the View, but I think putting it in the ViewModel is not appropriate (since it will be used by a specific View only). This is the simplest approach.

  2. Wrap every Chromosome in its own ViewModel, e.g. ChromosomeViewModel. Your existing ViewModel would take a collection of Chromosomes and expose an ObservableCollection<ChromosomeViewModel>. You would then create a ChromosomeView bound to each ViewModel, which would basically be what you have now in your ChromosomeDataTemplate. Since the ChromosomeView will be bound to a ChromosomeViewModel, which in turn wraps a single Chromosome, you can now provide a "modified-length" property directly in your ChromosomeViewModel.

If it's just for this, I suggest going with the ValueConverter. However, keep the second approach in mind for more complex scenarios.

Upvotes: 3

ptahmose
ptahmose

Reputation: 117

Why not use a converter here? See e.g. MSDN

Upvotes: 0

basarat
basarat

Reputation: 276195

You need to use a ValueConverter : http://blogs.msdn.com/b/bencon/archive/2006/05/10/594886.aspx

Upvotes: 0

Related Questions