首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用绑定按名称加载控件?

是否可以使用绑定按名称加载控件?
EN

Stack Overflow用户
提问于 2013-07-10 13:53:34
回答 2查看 55关注 0票数 0

在我的应用程序中,我需要一个不同I/O设备的集合,例如串行设备、OPC设备、USB设备等等。我使用了MEF框架来提供一种处理集合和允许添加新设备的方法。

我的项目看起来是这样的:

代码语言:javascript
复制
Atf.Model     'contains the model
Atf.Gui       'the views and view-models
Atf.Devices   'contains implementations of IDevice and exports them

许多设备需要配置,因此设备接口向自定义控件和相应的视图模型公开路径,该视图模型处理设备配置的编辑。我试图坚持MVVM模式,并希望尽可能地将视图和模型分开。同时,我希望尽可能地保持与设备集合的耦合。

Atf.Gui中,我有一个控件,它显示所有已发现的设备,并显示已激活的设备。当一个激活的设备被选中时,我想动态地显示它的编辑器。

我该怎么做?以下是一些(疯狂的)想法:

Idea-1只是在我的视图中加载一个UserControl -模型使用设备对象中的路径。这将打破MVVM的分离,使该部分“不可测试”。

代码语言:javascript
复制
public System.Windows.Controls.UserControl ConfigureControl 
{
   get 
   {
       // code to load the UserControl using the path property
   }
}

Idea-2让设备只公开一个视图模型,并使用映射(在设备存储库中定义)来获取视图。不知道该怎么做。

代码语言:javascript
复制
<myeditorcontainer>
    <ContainerControl Content="{Binding CurrentlySelectedDeviceViewModel}"/>
</myeditorcontainer>

在我看来,Idea-3,使用绑定加载控件。不确定这是否有可能。

代码语言:javascript
复制
<myeditorcontainer>
    <UserControl Path="{Binding CurrentlySelectedDeviceViewPath}" 
                 DataContext="{Binding CurrentlySelectedDeviceViewModel}"/>
</myeditorcontainer>
EN

回答 2

Stack Overflow用户

发布于 2013-07-10 14:00:36

我认为第二种想法是可行的。

假设ContainerControl是从ContentControl派生的,您应该能够为将要显示的每种类型的视图模型指定一个DataTemplate,然后根据视图模型的类型来呈现正确的UI。例如:

代码语言:javascript
复制
<myeditorcontainer>
    <ContainerControl Content="{Binding CurrentlySelectedDeviceViewModel}">
        <ContainerControl.Resources>
            <DataTemplate DataType="{x:Type ViewModel1Type}">
                <!-- controls for ViewModel1's UI -->
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModel2Type}">
                <!-- controls for ViewModel2's UI -->
            </DataTemplate>
        </ContainerControl.Resources>
    </ContainerControl>
</myeditorcontainer>

如果您需要比视图模型的类型更灵活来决定使用哪个模板,则可以指定一个ContentTemplateSelector。它将返回根据您所需的任何条件使用的正确模板。

票数 1
EN

Stack Overflow用户

发布于 2013-07-12 09:06:11

这就是我最后所做的,它似乎运作得很好。其关键特性是,视图模型与视图具有相同的名称,但附加了“Model”,视图模型派生自特定的类-- DeviceSettingsBase。

XAML:

代码语言:javascript
复制
<ContentControl Content="{Binding ConfigControl}"/>

视图-模型:

代码语言:javascript
复制
private RequiredDeviceViewModel rdvm;

public ContentControl ConfigControl
{
    get
    {
        // get assembly which contains this object
        Assembly assy = Assembly.GetAssembly(rdvm.Device.GetType());
        // get View-Type using the name defined in the Device
        Type viewType = assy.GetType(rdvm.Device.ConfigureControlResourceName, true);
        // get ViewModel-Type using the viewname + Model (may be null)
        Type viewModelType = assy.GetType(rdvm.Device.ConfigureControlResourceName + "Model", false);

        // instantiate the view control
        ContentControl view = (ContentControl)Activator.CreateInstance(viewType);
        // instantiate viewModel - if type not null
        if (viewModelType != null)
        {
            object viewModel = (object)Activator.CreateInstance(viewModelType, new object[] { rdvm.RequiredDevice.Config.ConfigString });
            view.DataContext = viewModel;
            // all device viewModels must derive from DeviceSettingsBase
            CurrentConfigViewModel = viewModel as DeviceSettingsBase;
            if (CurrentConfigViewModel != null)
            {
                CurrentConfigViewModel.IsEditable = IsEditable;
                CurrentConfigViewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(vmb_PropertyChanged);
                CurrentConfigViewModel.SettingsChanged += new SettingsChangedHandler(vmb_SettingsChanged);
            }
        }
        return view;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17572499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档