我在我的项目中使用Caliburn Micro
我有许多UserControl和从PropertyChangedBase
继承的viewmodel,我希望将这个UserControl添加到我的ShellView中的Canvas中。我不想使用IWindowManager
显示Windows,而是希望它们在Canvas中添加。
请帮忙。我怎么能这样做。
答案 0 :(得分:5)
如果您在ContentControl
中使用ShellView
,则可以挂钩到Caliburn.Micro的View-ViewModel绑定过程。
我认为在你的ShellViewModel
中,你有一堆属性ViewModel
。如果您在ContentControl
中放置ShellView
(如果这是您希望用来布置Shell的容器,则可能是Canvas
的孩子),然后将其命名为控制你希望它绑定到的ShellViewModel
中的属性名称,然后Caliburn的ViewModelBinder
将为你完成其余的工作。
例如,假设您有一个名为FizzViewModel
的VM和一个名为FizzView
的匹配视图(只是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的问题。
默认DataTemplate
Caliburn使用如下所示
<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>
你会注意到它使用的是ContentControl
,它具有我上面讨论过的一些优点。基本上,这将允许Caliburn为DataTemplateSelector
中的项目提供ItemsControl
类似的行为。因此,您可以将不同类型的VM添加到ItemsControl
绑定的集合中,此默认DataTemplate
将解析用于显示它的View类型。以下演示了一个如何实现您想要的非常简单的示例。
首先是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,请注意ItemsControl,它绑定到ShellViewModel上的Items属性
<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
的{{1}}示例,再创建2个,将名称更改为GreenViewModel
和RedView
并设置适当的背景使演示工作。
BlueView
这个例子放在一起时的作用是根据鼠标点击的位置在你的shell的<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>
上创建彩色方块。我认为你应该能够把它拿出来并扩展到你的需要。