简体   繁体   English

使用Prism,MVVM,MEF在WPF中动态生成控件

[英]Dynamically generating controls in WPF using Prism, MVVM, MEF

I am using WPF with Prism and MEF for my application. 我将WPF与Prism和MEF结合使用。 There was a need to create controls dynamically. 需要动态创建控件。 And so here is my problem!! 所以这是我的问题!!

As far as I know I should not be having code in my code behind (SomeFile.xaml.cs) to keep my code easily testable. 据我所知,我不应该在我的代码中使用代码(SomeFile.xaml.cs)来保持我的代码易于测试。 And so the code should be actually moved to ViewModel. 因此,代码应实际移至ViewModel。

But my code generates UI controls dynamically. 但是我的代码动态生成UI控件。 And I dont think that the ViewModel should know anything about the Controls. 我不认为ViewModel应该知道有关控件的任何信息。

So where and how should I go about writing this code?? 那么我应该在哪里以及如何去编写这段代码呢? What would be the right approach? 什么是正确的方法? Hope I made myself clear! 希望我清楚自己!

Thanks 谢谢

When working with WPF/MVVM, your data layer is your application (the DataContext ), and you use things like Templates to tell WPF how to draw your application components to the UI. 使用WPF / MVVM时,您的数据层就是您的应用程序( DataContext ),您可以使用Templates方式告诉WPF如何将应用程序组件绘制到UI。

For example, suppose you're given the task to dynamically render a bunch of controls. 例如,假设您被赋予了动态渲染一组控件的任务。

The WinForms way might have been to loop through your objects, create a UI control for each object, then add the UI control to the screen. WinForms方式可能是遍历对象,为每个对象创建UI控件,然后将UI控件添加到屏幕。

However with WPF/MVVM, you would instead create a class representing each object (a Model ), and give WPF a list of those classes to display. 但是,使用WPF / MVVM时,您可以创建一个代表每个对象的类( Model ),并为WPF提供要显示的这些类的列表。

There are many different controls WPF can use to draw a list of objects, but the most basic of them is probably an ItemsControl . WPF可以使用许多不同的控件来绘制对象列表,但是其中最基本的控件可能是ItemsControl I have some examples of a simple ItemsControl on my blog if you're interested. 如果您有兴趣, 我在博客上有一些简单的ItemsControl示例。

Now even though you've given WPF the list of your objects to render, and told it what control to use to render the list, it still probably doesn't know how to draw your object. 现在即使你给WPF提供了要渲染的对象列表,并告诉它使用什么控件来渲染列表,它仍然可能不知道如何绘制对象。 The usual solution for this is to include an XAML template of some kind to tell it how to draw your object. 通常的解决方案是包含某种XAML模板,告诉它如何绘制对象。

Here's a simple example template that is used to tell WPF how to draw an object of type MyClassObject : 这是一个简单的示例模板,用于告诉WPF如何绘制MyClassObject类型的对象:

<DataTemplate DataType="{x:Type local:MyClassObject}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Name:" />
        <TextBox Text="{Binding Name}" />
    </StackPanel>
</DataTemplate>

I hope that helps get you going in the right direction :) 我希望这能帮助您朝正确的方向前进:)

From my perspective, the view has the responsibility to render the data/model provided by the viewmodel. 从我的角度来看,视图有责任呈现viewmodel提供的数据/模型。 While it is ideal to keep as much of the model->view translation logic in the viewmodel, creation of controls adds significant complexity to move to the viewmodel, because of the coupling or infrastructure that it could add. 虽然在视图模型中保留尽可能多的模型->视图转换逻辑是理想的,但控件的创建会增加添加到视图模型的复杂性,因为可能会添加耦合或基础结构。

While you could: 1) Give the viewmodel direct access to the view, allowing it to create controls directly This adds coupling... 2) Create an interface on the view to manipulate controls This means the view must be passed (not simply bound) to the viewmodel 3) Create an abstraction of controls to bind to the view, and have the view render based on the abstraction created by the viewmodel This adds a maintenance nightmare as your control set expands. 虽然你可以:1)让viewmodel直接访问视图,允许它直接创建控件这增加了耦合... 2)在视图上创建一个接口来操作控件这意味着必须传递视图(不是简单地绑定)到视图模型3)创建绑定到视图的控件的抽象,并基于由视图模型创建的抽象来渲染视图。这随着控件集的扩展增加了维护的噩梦。

I suggest exposing the model (either directly or wrapped in micro-viewmodels) via a property on the main viewmodel, and binding that to a property on the view via xaml, such that any PropertyChanged on the viewmodel will send an update to the view. 我建议通过主视图模型上的属性公开模型(直接或包装在微视图模型中),然后通过xaml将其绑定到视图上的属性,这样,视图模型上的任何PropertyChanged都会向视图发送更新。 Use the model information and your control creation logic inside the view to clear and re-create the controls and bind the model dynamically to the controls you create. 在视图内部使用模型信息和控件创建逻辑来清除并重新创建控件,并将模型动态绑定到您创建的控件。 This will simplify both the creation and binding of the controls, and you won't have to practice any voodoo to get information entered into the controls back into your model. 这将简化控件的创建和绑定,并且您无需练习任何伏都教即可将输入到控件中的信息返回到模型中。

Note that even if you created an intermediary class (an attached behavior, adorner, or something else), it will still need to be able to access the view's control structure directly to attach the generated controls to the visual tree, which may cause other problems. 请注意,即使您创建了一个中间类(附加的行为,装饰器或其他),它仍将需要能够直接访问视图的控件结构以将生成的控件附加到可视树,这可能会导致其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM