我Caliburn Micro
在我的项目中使用,并且我有许多 UserControls 和他们的 viewmodel 继承自PropertyChangedBase
,我希望将此 UserControl 添加到我的 ShellView 中的 Canvas 中。我不想IWindowManager
从显示 Windows 中使用,而是希望将它们添加到画布中。
请帮忙。我怎样才能做到这一点。
我Caliburn Micro
在我的项目中使用,并且我有许多 UserControls 和他们的 viewmodel 继承自PropertyChangedBase
,我希望将此 UserControl 添加到我的 ShellView 中的 Canvas 中。我不想IWindowManager
从显示 Windows 中使用,而是希望将它们添加到画布中。
请帮忙。我怎样才能做到这一点。
如果您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 的问题。
默认的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>
您会注意到它使用 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 个,将名称更改为RedView
和BlueView
并适当地设置背景以使演示正常工作。
<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
根据鼠标点击的位置在你的外壳上创建彩色方块。我认为你应该能够接受这个并将其扩展到你的需要。