是否在模型中包含视图特定信息

时间:2010-11-28 15:48:29

标签: c# wpf mvvm c#-4.0

我目前有一个包含以下属性的类

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

    public int Number
    {
        get;
        set;
    }

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

我有一个绑定到我的视图模型的列表框数据。项目来源是绑定到 Observable 染色体对象 ChromosomeList 的数据。

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

列表框项目的ItemTemplate为 ChromosomeDataTemplate ,如下所示。

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

在这种情况下,我希望网格的高度属性绑定到染色体的长度属性。但是,由于长度非常大,我需要它只是实际值的一小部分。我可以通过以下方式做到这一点:

  • 为修改后的高度制作新属性

但是,我觉得这不符合MVVM模式。在数据绑定时有没有办法修改长度值?

3 个答案:

答案 0 :(得分:3)

Chromosome是您的模特。您的XAML代码位于您的视图中。假设的“修改长度”值应该驻留在ViewModel中。

你说修改高度的新属性不是MVVM是正确的(当然,这通常是个坏主意)。

为了更好的方法,通常会将修改后的长度属性放在ViewModel中。但是,现在问题是您的ViewModel有一个ObservableCollection<Chromosome>,因此无法为每个Chromosome个实例提供一个简单的修改长度属性。

因此,您有两种选择:

  1. 实施ValueConverter,将原始Length翻译为适当的Grid.Height。这可以在ViewModel或View中,但我认为将它放在ViewModel中是不合适的(因为它仅由特定的View使用)。这是最简单的方法。

  2. 在自己的ViewModel中包装每个Chromosome,例如ChromosomeViewModel。您现有的ViewModel会收集Chromosome个集合并公开ObservableCollection<ChromosomeViewModel>。然后,您将创建一个绑定到每个ViewModel的ChromosomeView,这基本上就是您现在ChromosomeDataTemplate中的内容。由于ChromosomeView将绑定到ChromosomeViewModel,后者又包含一个Chromosome,因此您现在可以直接在ChromosomeViewModel中提供“修改长度”属性。

  3. 如果只是为了这个,我建议使用ValueConverter。但是,对于更复杂的场景,请牢记第二种方法。

答案 1 :(得分:0)

答案 2 :(得分:0)

为什么不在这里使用转换器?参见例如MSDN