绑定到UserControl的集合

时间:2014-09-16 14:06:55

标签: wpf xaml mvvm user-controls

我有一个用WPF(MVVM)编写的应用程序,它基于某些条件,将创建不同UserControls的实例,这些UserControls是完全独立的,用于显示某些信息。他们内部有一些自定义逻辑,比如计时器等,所以我不能使用模板。

现在我遇到了一个问题,我想在ViewModel中创建一个UserControl列表,并将主机UI绑定到它。问题是我不知道如何绑定和绑定什么。在非MVVM项目中,您只需获得要放置控件的布局,并将其作为子项添加到那里。在MVVM应用程序中,我不知道如何做到这一点。我想有一个带有ItemsSource的WrapPanel,它将根据UserControls添加所有控件并根据需要调整自身大小。

有人可以建议解决方案吗?

修改 我的ViewModel现在公开了 IMyDriver ObservableCollection 。这就是我的想法,打破一点MVVM以获得我接下来描述的内容: 现在,每个IMyDriver可以是不同类型的驱动程序,并且可以实现不同的其他接口。我需要UI来创建特定的UserControls,这些UserControls知道如何根据这些驱动程序的功能从这些驱动程序中获取最大值。简而言之,UserControls通过驱动程序连接到设备以轮询数据。每个UserControl都以特定的方式完成它。

3 个答案:

答案 0 :(得分:1)

通过为每个UserControl中的数据声明特定数据类型类并定义DataTemplateUserControl中展示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所回答的内容,我找到了解决问题的方法。

所以:

  1. 我不会通过保持ViewModel类型完整来破坏MVVM。

  2. 我在Window的Resources标签中创建DataTemplates,在每个数据模板中,我将DataTemplate指定为我在另一个程序集中定义的UserControl(UICommons)

    <DataTemplate x:Key="IMultiChannelMeasurementDCDataTemplate">
        <uicommon:MeasurementMax8ChannelMonitoringUserControl/>
    </DataTemplate>
    
  3. 我在应用程序集中创建了一个模板选择器,并根据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}"/>
    
  4. 我在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>
    
  5. 我喜欢基于不同的驱动程序动态创建UserControl!
  6. P.S。我赞成Will的评论和Sheridan的回答,因为如果没有这些,我将无法找到解决方案。 THX!

答案 2 :(得分:0)

  

他们内部有一些自定义逻辑,比如计时器等,所以我不能使用模板。

这不遵循。我想你可能对WPF的功能有误解。

另外,因为你想使用MVVM:绑定到UserControls列表正在破坏模式。视图模型应该只引用其他视图模型(和模型);他们对UI一无所知。绑定到视图模型的集合,这些视图模型将UserControls视为其视图(请考虑使用implicit DataTemplates)。要绑定WrapPanel,请使用ItemsControl并相应地设置其ItemsPanel