Caliburn Micro->从多个视图/用户控件/自定义控件组成视图 [英] Caliburn Micro -> Composing Views from multiple Views/UserControls/CustomControls

查看:88
本文介绍了Caliburn Micro->从多个视图/用户控件/自定义控件组成视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在CM管理的窗口中重新使用和组成零件?我发现了有关使用两个UserControl绑定到同一ViewModel的帖子,但是如果我想在同一个窗口中组成多个视图和视图模型,就不会那么多. (组成主视图"的每个视图的视图模型)

How is it possible to re-use and compose parts in CM managed windows? I have found posts regarding using two UserControls to bind to the same ViewModel, but not so much if I want to have multiple views and viewmodels all composed in the same window. (a viewmodel for each view composed into a "master view")

我的问题的第一部分将是如何分解组件以供重复使用?如果我在窗口中有两个区域,一个是数据网格,另一个是带有标签和文本框的详细信息视图,这些区域应该位于单独的用户控件,自定义控件或窗口中吗?理想情况下,每个窗口都是独立的,因此可以分开使用,并在其他窗口中使用.

The first part of my question would be how to break up components for re-use? If I have two areas of a window where one is a datagrid and another is a details view with labels and text boxes should these be in separate usercontrols, customcontrols or windows? Each one would ideally be stand alone so they can be separated and used in other windows.

因此,如果将它们分开,我将得到2个视图模型和2个视图.现在假设我要创建3个窗口,一个窗口带有第一个视图,第二个带有第二个视图,第三个带有两个视图.如何使用CM为每个窗口创建窗口并将每个视图连接到其视图模型?从我看到的示例中,我在窗口中看到的大部分是单个视图和视图模型.

So I would end up with 2 viewmodels and 2 views if they were separated. Now lets say I would like to create 3 windows, one window with the first view, the second with the second view and a third with both views. How do I use CM to create the window for each and wire up each view to their viewmodel? From the examples I have seen I see for the most part a single view and viewmodel in a window.

推荐答案

我认为我以前做过与您要求的类似的事情.我一直在玩TabControl之一,目的是为我喜欢玩的游戏托管几种不同的工具.

I think I've previously done something similar to what you're asking. I'd been playing around with one of the TabControl with the intention of hosting several different tools for a game I enjoy playing.

主要工具是类似于通用文件浏览器类型程序的项目浏览器,并且与Jon上面描述的类似.我将解释一些可能与您感兴趣/相关的部分(我删除了一些稍微晦涩的命名).

The main tool is an item browser similar to the usual file explorer type programs, and similar to what Jon has described above. I'll explain some of the parts which may be of interest/relevance (I've removed some of the slightly obscure naming).

ExplorerView主选项卡基本上与Jon描述的选项卡完全相同(希望这是一个好兆头-表示我不疯狂= D)

The main ExplorerView tab is essentially exactly the same the one Jon describes (which is hopefully a good sign - means I'm not crazy =D)

<UserControl x:Class="ItemsBrowser.Views.ItemsTabView"
<!-- namespaces -->
>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <ContentControl x:Name="ItemsExplorer" Grid.Column="0" Grid.Row="0" />
        <GridSplitter HorizontalAlignment="Right" VerticalAlignment="Stretch" 
                      ResizeBehavior="PreviousAndNext" Width="4" Grid.Column="1" Background="#FFAAAAAA" />
        <ContentControl x:Name="PanelView" Grid.Column="2" Grid.Row="0" />
    </Grid>   
</UserControl>

关联的ViewModel包含另外两个ViewModels,用于组成主浏览器视图:

The associated ViewModel holds two other ViewModels, used for composing the main explorer view:

public class ItemsTabViewModel : Conductor<IScreen>.Collection.AllActive 
{
    public ItemsViewModel ItemsExplorer { get; set; }
    public ExplorerPanelViewModel PanelView { get; set; }

    // Ctor etc.
}

ItemsExplorer包含一个TreeView样式控件,允许用户从游戏中探索Item的各种类别.它在应用程序的多个位置使用,并由几个不同的控件组成.

The ItemsExplorer hosts a TreeView style control, allowing users to explore various categories of Item from the game. This is used in multiple places in the application, and is composed into a few different controls.

ExplorerPanelView是右侧的面板,根据用户正在查看的项目类型而更改为显示多个ViewModels.用户还可以选择在ExplorerPanelView中显示的ViewModel上切换几个不同的Views.

The ExplorerPanelView is a panel on the right hand side, that changes to display a number of ViewModels, based on what type of item the user is viewing. The user also have the option to toggle a few different Views over the ViewModel displayed in the ExplorerPanelView.

ExplorerPanelView看起来像:

<UserControl x:Class="MIS_PTBrochure.Views.ExplorerPanelView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:cal="http://www.caliburnproject.org">
    <Grid>
        <ContentControl cal:View.Model="{Binding Path=ActiveItem}" 
                        cal:View.Context="{Binding Path=ActiveItem.State}"
                        Content="Select a folder."/>
    </Grid>
</UserControl>

以及后面的ExplorerPanelViewModel:

public class ExplorerPanelViewModel : Conductor<IScreen>.Collection.OneActive,
    IHandle<ItemSelectedEvent> // More events.
{
    public ItemViewModel ItemInfo { get; set; }
    public CategoryFolderViewModel CategoryFolderInfo { get; set; }

    public ExplorerPanelViewModel()
    {
        // My helper to access the `Caliburn.Micro` EventAggregator.
        EventAggregatorFactory.EventAggregator.Subscribe(this);

        // Other code
    }

    public void Handle(ItemSelectedEvent message)
    {
        // Other code to check active status
            ItemInfo = message.selected;
            ActivateItem(ItemInfo);
    }

    protected override void OnDeactivate(bool close)
    {
        Debug.WriteLine("Deactivated " + this.ToString() + close.ToString());
        if (close) { EventAggregatorFactory.EventAggregator.Unsubscribe(this); }
        base.OnDeactivate(close);
    }

    // Other code
}

我试图删除许多无关的代码.本质上,我再次托管多个ViewModels作为属性(尽管您可以保存一个集合),并在我的ItemsExplorerViewModel引发适当的事件时激活相关的ViewModel.我正在使用Caliburn.Micro EventAggregator 处理多个ViewModels.

I've tried to remove a lot of non-relevant code. Essentially I'm again hosting multiple ViewModels as properties (although you could hold a collection) and activating the relevant ViewModel when an approriate event is raised by my ItemsExplorerViewModel. I'm using the Caliburn.Micro EventAggregator to handle communication between multiple ViewModels.

从理论上讲,您可以省去这些属性,而只需激活事件本身中引用的ViewModels.

In theory you could dispense with the properties, and just activate the ViewModels referenced in the events themselves.

关于cal:View.Contextcal:View.Model-我正在使用所有这些用户来切换不同的可用View状态(该面板中显示的每个ViewModel都继承自基本的ViewModel类, State属性).

Regarding the cal:View.Context and cal:View.Model - I'm using these all the user to toggle different available View states available (each ViewModel displayed in that panel inherits from a base ViewModel class which all have a State property).

在一些地方,我使用相同的ViewsViewModels弹出不同的窗口.为此,我使用了Caliburn.Micro WindowManager.官方文档中没有很多有关此内容的信息(最好搜索Google和CM讨论),这确实可以做到.

There are a few places where I pop up different windows using some of the same Views and ViewModels. To achieve this, I make use of the Caliburn.Micro WindowManager. There isn't a great deal about it in the official documentation (you're best off searching Google and the CM discussions), it pretty does what is says on the tin.

如果您查看Caliburn.Micro.IWindowManager界面,将会看到一些可以从WindowManager实例调用的便捷方法.

If you have a look at the Caliburn.Micro.IWindowManager interface you'll see some handy methods that you can call from a WindowManager instance.

public interface IWindowManager
{
    bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null);
    void ShowPopup(object rootModel, object context = null, IDictionary<string, object> settings = null);
    void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null);
}

因此,为了弹出带有您选择的ViewModel的新Window,我按照以下方式进行了操作:

So to pop up a new Window with a ViewModel of your choice, I did something along these lines:

// Some basic Window settings.
dynamic settings = new ExpandoObject();
    settings.Title = "Test Window";
    settings.WindowStartupLocation = WindowStartupLocation.Manual;
    settings.SizeToContent = SizeToContent.Manual;
    settings.Width = 450;
    settings.Height = 300;

    var TestViewModel new TestViewModel();
    WindowManagerFactory.WindowManager.ShowWindow(this.classSearch, null, settings);

Caliburn.Micro应该再次将您的Views解析为正确的ViewModels.

Caliburn.Micro should again, resolve your Views to the correct ViewModels.

希望那里有些有用的东西.我通过几次设计迭代就得出了这种解决方案,因此这可能不是解决其中某些问题的最佳方法.如果有人有建设性的批评,请让我知道= D

Hopefully there's something useful in there somewhere. I sort of arrived at this solution through a few design iterations, so this may not be the optimal approach to some of these problems. If anyone has any constructive criticism, please let me know =D

这篇关于Caliburn Micro-&gt;从多个视图/用户控件/自定义控件组成视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆