1

Caliburn Micro在我的项目中使用,并且我有许多 UserControls 和他们的 viewmodel 继承自PropertyChangedBase,我希望将此 UserControl 添加到我的 ShellView 中的 Canvas 中。我不想IWindowManager从显示 Windows 中使用,而是希望将它们添加到画布中。

请帮忙。我怎样才能做到这一点。

4

1 回答 1

5

如果您ContentControl在您的内部使用,您ShellView可以挂钩到 Caliburn.Micro 的 View-ViewModel 绑定过程。

我假设在你的ShellViewModel身上你有一堆暴露的属性,它们是ViewModel. 如果您将 a 放置ContentControl在您的ShellView(这可能是Canvas您希望用于布局 Shell 的容器上/作为其子项),然后使用ShellViewModel您希望绑定的属性名称来命名该控件到,然后 Caliburn'sViewModelBinder将为您完成剩下的工作。

例如,假设您有一个称为 VMFizzViewModel和一个匹配的 View 称为FizzView(这只是 a UserControl),并且您希望FizzView出现在您的设备上,ShellView您可以执行以下操作...

一个脱光的背影ShellViewModel

public class ShellViewModel : Screen, IShell
{
    public ShellViewModel(FizzViewModel theFizz)
    {
        TheFizz = theFizz;
    }

    public FizzViewModel TheFizz { get; set; }
}

及其匹配ShellView

<UserControl x:Class="ANamespace.ShellView">
    <Canvas> 
        <ContentControl x:Name="TheFizz"></ContentControl>
    </Canvas> 
</UserControl>

在这里,因为它ContentControl被命名为 TheFizz,它将被 Caliburn 绑定到您的 VM 上具有该名称的属性(类型之一FizzViewModel

这样做意味着您不必在您UserControl的 上使用它们的真实类型,您ShellView可以让 Caliburn 通过约定为您完成工作(这意味着如果您只需添加一点,就很容易换出 TheFizz 类型接口间接)。

更新

从您在评论中提供的额外信息中,我现在可以看到您实际上正在查看一个需要 ItemsControl 的问题。

默认的DataTemplateCaliburn 使用如下所示

<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
              xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro">  
    <ContentControl cal:View.Model="{Binding}"   
                    VerticalContentAlignment="Stretch"  
                    HorizontalContentAlignment="Stretch" />  
</DataTemplate>

您会注意到它使用 a ContentControl,正如我在上面讨论的那样,它具有一些优点。基本上,这将允许 Caliburn 为DataTemplateSelector您的ItemsControl. 因此,您可以将不同类型的虚拟机添加到您ItemsControl绑定的集合中,此默认设置DataTemplate将解析用于显示它的视图类型。以下演示了一个非常简单的示例,说明如何实现您想要的。

首先是ShellViewModel,记下BindableCollection命名的Items

[Export(typeof(IShell))]
public class ShellViewModel : IShell 
{
    public ShellViewModel()
    {
        Items = new BindableCollection<Screen>();
        _rand = new Random();
    }

    public BindableCollection<Screen> Items { get; set; }

    private Random _rand;

    public void AddItem()
    {
        var next = _rand.Next(3);
        var mPosition = System.Windows.Input.Mouse.GetPosition(App.Current.MainWindow);
        switch (next)
        {
            case 0:
                {
                    Items.Add(new BlueViewModel
                        {
                            X = mPosition.X,
                            Y = mPosition.Y,
                        });
                    break;
                }

            case 1:
                {
                    Items.Add(new RedViewModel
                    {
                        X = mPosition.X,
                        Y = mPosition.Y,
                    });
                    break;
                }
            case 2:
                {
                    Items.Add(new GreenViewModel
                    {
                        X = mPosition.X,
                        Y = mPosition.Y,
                    });
                    break;
                }
            default:
                break;
        }
    }
}

然后是一些您想在 Shell 中显示的虚拟 VM 类型。这些可以是/做任何你喜欢的事情:

public abstract class SquareViewModel : Screen
{
    public double X { get; set; }
    public double Y { get; set; }
}

public class BlueViewModel : SquareViewModel
{

}

public class RedViewModel : SquareViewModel
{

}

public class GreenViewModel : SquareViewModel
{

}

现在是一个 ShellView,注意绑定到 ShellViewModel 上的 Items 属性的 ItemsControl

<Window x:Class="WpfApplication2.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro">

<Grid >
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <ItemsControl x:Name="Items"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas cal:Message.Attach="[Event MouseLeftButtonUp] = [Action AddItem()]"
                            Background="Transparent"></Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
                    <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>
</Grid>
</Window>

UserControl还有一个用于显示 的示例,再GreenViewModel创建 2 个,将名称更改为RedViewBlueView并适当地设置背景以使演示正常工作。

<UserControl x:Class="WpfApplication2.GreenView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Width="30"
             Height="30">
    <Grid Background="Green"></Grid>
</UserControl>

这个例子放在一起是Canvas根据鼠标点击的位置在你的外壳上创建彩色方块。我认为你应该能够接受这个并将其扩展到你的需要。

于 2012-05-09T03:03:00.327 回答