我是MVVM的新手,在下面的场景中需要帮助。
我的视图中添加了一个Stack面板,现在我必须通过viewmodel动态添加几个控件到这个堆栈面板。为此,我需要在viewmodel中使用堆栈面板的句柄。任何人都可以指导我如何在我的viewmodel中访问堆栈面板。
我在其他人看来可以通过使用Dependency属性来完成它。但我仍然无法找到解决这个问题的方法。
答案 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>