我有一个用WPF(MVVM)编写的应用程序,它基于某些条件,将创建不同UserControls的实例,这些UserControls是完全独立的,用于显示某些信息。他们内部有一些自定义逻辑,比如计时器等,所以我不能使用模板。
现在我遇到了一个问题,我想在ViewModel中创建一个UserControl列表,并将主机UI绑定到它。问题是我不知道如何绑定和绑定什么。在非MVVM项目中,您只需获得要放置控件的布局,并将其作为子项添加到那里。在MVVM应用程序中,我不知道如何做到这一点。我想有一个带有ItemsSource的WrapPanel,它将根据UserControls添加所有控件并根据需要调整自身大小。
有人可以建议解决方案吗?
修改 我的ViewModel现在公开了 IMyDriver 的 ObservableCollection 。这就是我的想法,打破一点MVVM以获得我接下来描述的内容: 现在,每个IMyDriver可以是不同类型的驱动程序,并且可以实现不同的其他接口。我需要UI来创建特定的UserControls,这些UserControls知道如何根据这些驱动程序的功能从这些驱动程序中获取最大值。简而言之,UserControls通过驱动程序连接到设备以轮询数据。每个UserControl都以特定的方式完成它。
答案 0 :(得分:1)
通过为每个UserControl
中的数据声明特定数据类型类并定义DataTemplate
在UserControl
中展示App.xaml
,您可以非常简单轻松地完成此操作文件:
<DataTemplate DataType="{x:Type YourViewModelsPrefix:YourViewModel">
<YourViewsPrefix:YourView />
</DataTemplate>
<DataTemplate DataType="{x:Type YourViewModelsPrefix:YourOtherViewModel">
<YourViewsPrefix:YourOtherView />
</DataTemplate>
<DataTemplate DataType="{x:Type YourViewModelsPrefix:AnotherViewModel">
<YourViewsPrefix:AnotherView />
</DataTemplate>
现在,只要Framework遇到这些视图模型类的实例,它就会呈现关联的视图/ UserControl
。您可以使用ContentControl
这样的属性来显示它们:
<ContentControl Content="{Binding YourViewModelProperty}" />
...
public YourBaseViewModelClass YourViewModelProperty { get; set; }
确保所有视图模型都扩展此类:
public YourViewModel : YourBaseViewModelClass { }
...
public AnotherViewModel : YourBaseViewModelClass { }
然后您可以交换每个视图模型(并显示每个相关视图),如下所示:
YourViewModelProperty = new AnotherViewModel();
答案 1 :(得分:1)
根据Will评论的内容以及Sheridan所回答的内容,我找到了解决问题的方法。
所以:
我不会通过保持ViewModel类型完整来破坏MVVM。
我在Window的Resources标签中创建DataTemplates,在每个数据模板中,我将DataTemplate指定为我在另一个程序集中定义的UserControl(UICommons)
<DataTemplate x:Key="IMultiChannelMeasurementDCDataTemplate">
<uicommon:MeasurementMax8ChannelMonitoringUserControl/>
</DataTemplate>
我在应用程序集中创建了一个模板选择器,并根据DataTypes实现的接口,返回正确的DataTemplate,我在同一个Window的Resources标签中分配
<!-- DataTemplate Selector -->
<local:DriverComponentDataTemplateSelector x:Key="templateSelector"
DefaultDCDataTemplate="{StaticResource DefaultDCDataTemplate}"
IIhcDCDataTemplate="{StaticResource IIhcDCDataTemplate}"
IMultiChannelMeasurementDCDataTemplate="{StaticResource IMultiChannelMeasurementDCDataTemplate}"
IProgrammablePowerSourceDCDataTemplate="{StaticResource IProgrammablePowerSourceDCDataTemplate}"
IEnvDCDataTemplate="{StaticResource IEnvDCDataTemplate}"/>
我在Window中创建一个ItemsControl,其中包含以下XAML代码,它将自身绑定到我的ObservableCollection项
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemTemplateSelector="{StaticResource templateSelector}" ItemsSource="{Binding DriverComponentsInfo}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" x:Name="ucWrapPanel">
</WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
答案 2 :(得分:0)
他们内部有一些自定义逻辑,比如计时器等,所以我不能使用模板。
这不遵循。我想你可能对WPF的功能有误解。
另外,因为你想使用MVVM:绑定到UserControls
列表正在破坏模式。视图模型应该只引用其他视图模型(和模型);他们对UI一无所知。绑定到视图模型的集合,这些视图模型将UserControls
视为其视图(请考虑使用implicit DataTemplates
)。要绑定WrapPanel
,请使用ItemsControl
并相应地设置其ItemsPanel
。