如何在ViewModel(MVVM)中处理控件

时间:2012-12-20 17:29:02

标签: mvvm

我是MVVM的新手,在下面的场景中需要帮助。

我的视图中添加了一个Stack面板,现在我必须通过viewmodel动态添加几个控件到这个堆栈面板。为此,我需要在viewmodel中使用堆栈面板的句柄。任何人都可以指导我如何在我的viewmodel中访问堆栈面板。

我在其他人看来可以通过使用Dependency属性来完成它。但我仍然无法找到解决这个问题的方法。

4 个答案:

答案 0 :(得分:4)

首先要注意的事情。 MVVM模式中ViewModel的目的是提供与View的分离。因此,您的ViewModel应该不了解View本身以及View中包含的控件。其次,您应该尝试做的是将View绑定到ViewModel的属性(理解您的ViewModel充当View的DataContext)。通常,您可以将控件的ItemsSource属性绑定到ViewModel中的某个集合。但是,您会注意到StackPanel没有实现ItemsSource依赖项属性。而是使用ItemsControl代替StackPanel。我建议对MVVM模式和绑定机制进行一些额外的阅读,以便进一步澄清。

答案 1 :(得分:0)

完全赞同Backlash, 您的ViewModel和您的View似乎过于耦合; 互联网上有很多资源,但我喜欢这里的一些资源:

答案 2 :(得分:0)

我之前使用用户控件完成了这项工作。我有一组对象需要动态地在StackPanel中进行控制。您也可以使用任何控件执行此操作...我将在此示例中使用TextBlock。

使用您希望包装在堆栈面板中的控件创建数据模板: (MyText是集合对象中的属性...见下文)

<DataTemplate x:Key="MyTemplate">
   <Grid Margin="0">
       <StackPanel>     
         <TextBlock Text="{Binding Path=MyText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
        </TextBlock>
      </StackPanel>
   </Grid>
</DataTemplate>

然后关键是使用ItemsControl绑定到一组对象: (该集合在您的viewModel上)

<ItemsControl   
 ItemsSource="{Binding ACollection, Mode=TwoWay,  UpdateSourceTrigger=PropertyChanged}"
 ItemTemplate=" {StaticResource MyTemplate}" Background="Transparent">
</ItemsControl>

因此,例如,如果“ACollection”中有3个项目,如果集合中有5个将有5个TextBlocks等,则会有3个TextBlock堆叠在一起。

答案 3 :(得分:0)

谢谢大家的帮助,我解决了这个问题

在视图模型中,我创建了FrameWorkElement类型的ObservableCollection,它可以保存将在运行时决定的任何其他控件。控件可以是文本框或按钮。

 Public  ObservableCollection < FrameWorkElement > Test
 {
        get{....} set{...}
 }

现在我可以添加/设置任何其他控件到Test

 Tets.Add(new TextBox()); Or Button , this will be decided at runtime.

现在将此“Test”绑定到ItemsControl。

 <ItemsControl x:Name="itemsControl" ItemsSource={Biding Test}>
 </ItemsControl>