wpf MVVM 和控件的动态生成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18560776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:33:26  来源:igfitidea点击:

MVVM and dynamic generation of controls

c#wpfxamlmvvm

提问by user1590636

i've written a tool that generates sql queries using GUI, i want to rewrite the tool using MVVM and WPF, every sql column type has a different control as you can see in the following image

我编写了一个使用 GUI 生成 sql 查询的工具,我想使用 MVVM 和 WPF 重写该工具,每个 sql 列类型都有不同的控件,如下图所示

enter image description here

在此处输入图片说明

i add a column filter control based on the sql column type, and i generate the controls using code, just like i used to do in windows forms.

我添加了一个基于 sql 列类型的列过滤器控件,并使用代码生成控件,就像我以前在 Windows 窗体中所做的一样。

  1. in MVVM i've read that the view is writtien enteirly using XAML, does MVVM suite such application where i have to add different user controls dynamically to a stack panel?
  2. The controls won't exist in the view unless some column is double clicked, that means the control won't be available in the xaml and won't be hidden or collapsed.
  3. is there any way that i can avoid the bindings in the code behind?
  4. should i create a user control for each column type?
  5. in general what is the best approach to devlop such application with complex and dynamic ui using mvvm?
  1. 在 MVVM 中,我读到该视图完全使用 XAML 编写,MVVM 是否适合这样的应用程序,我必须将不同的用户控件动态添加到堆栈面板?
  2. 除非双击某些列,否则视图中将不存在控件,这意味着控件在 xaml 中不可用,也不会隐藏或折叠。
  3. 有什么办法可以避免后面代码中的绑定?
  4. 我应该为每种列类型创建一个用户控件吗?
  5. 一般来说,使用 mvvm 开发具有复杂和动态 ui 的此类应用程序的最佳方法是什么?

回答by oxfn

Guess I know how to achieve that, but it is very complex stuff. First you should comprehend MVVM basic concepts. Main ViewModel should be a class with ObservableCollectionof ViewModels, each of them represents a column with its data and properties.

我猜我知道如何实现这一点,但这是非常复杂的事情。首先你应该理解MVVM的基本概念。Main ViewModel 应该是一个包含ObservableCollectionViewModel的类,它们中的每一个都代表一个包含其数据和属性的列。

interface IViewModel : INotifyPropertyChanged,IDisposable
{
}

interface IColumnViewModel : IViewModel
{
}

class ViewModelBase : IViewModel
{
    // ... MVVM basics, PropertyChanged etc. ...
}

class MainViewModel : ViewModelBase
{
    ObservableCollection<IColumnViewModel> Columns {get; set}
}

In View I suppose something like ItemsControlwith ItemTemplate, that should embed ContentControlwith DataTemplate, that shall be automatically selected by WPF according to binded DataContextof list item. StackPanelitself is not suitable for that, but it can be invoked as ItemsPanelTemplate

在 View 中,我想像ItemsControlwith一样ItemTemplate,应该嵌入ContentControlwith DataTemplate,WPF 会根据绑定DataContext的列表项自动选择。StackPanel本身不适合那个,但它可以被调用为ItemsPanelTemplate

<Window
    xmlns:v="clr-namespace:WpfApplication.Views"
    xmlns:vm="clr-namespace:WpfApplication.ViewModels">
    <Window.Resources>
        <DataTemplate DataType="{x:Type TypeName=vm:TextColumnViewModel}">
            <v:TextColumnView/>
        </DataTemplate>
    </Window.Resources>
    <ItemsControl
        ItemsSource="{Binding Columns}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

So, you should build View/ViewModel pair for every column type.

因此,您应该为每个列类型构建 View/ViewModel 对。

Hope, my example will help. Good luck with your girlfriend and MVVM :)

希望,我的例子会有所帮助。祝你女朋友和 MVVM 好运 :)

回答by Yaser Moradi

If I've understood your scenario correctly : You can use Data Templates & Items Templates For example I've written an application which loads Data into Collection and then shows each item of that collection in a Wrap Panel [ Or stack panel ] based on defined data template. And Wrap penel items are in sync by the collection itself within two way binding You should consider using Observable Collections to achieve this goal Then you can fill the collection and see the results on a view I hope this helps

如果我正确理解了您的场景:您可以使用数据模板和项目模板例如,我编写了一个应用程序,将数据加载到集合中,然后根据定义在包装面板 [或堆栈面板] 中显示该集合的每个项目数据模板。并且 Wrap penel 项目在两种方式绑定中由集合本身同步 您应该考虑使用 Observable Collections 来实现此目标然后您可以填充集合并在视图上查看结果我希望这会有所帮助

回答by paqogomez

To write something like this in MVVM, you would have one view that is say, your content area. That view would have a view model, one of the properties of that view model would be a view, or several properties of that view model would be a view. It takes a bit to wrap your head around at times, but if you use Inversion of Control and Dependency Injection properly a view of views is very manageable in an MVVM pattern.

要在 MVVM 中编写类似的内容,您将拥有一个视图,即您的内容区域。该视图将有一个视图模型,该视图模型的一个属性将是一个视图,或者该视图模型的多个属性将是一个视图。有时需要花点时间思考,但是如果您正确使用控制反转和依赖注入,则视图视图在 MVVM 模式中非常易于管理。

回答by zmbq

Well, your view isn't written entirely in XAML - you generate controls in C#.

好吧,您的视图并非完全用 XAML 编写 - 您用 C# 生成控件。

I don't think you'll gain something from rewriting this and fitting it into an MVVM mold. Just keep the code as it is now and enjoy.

我不认为你会从重写这个并将其安装到 MVVM 模具中获得什么。只需保持代码原样即可享受。