我有一个 MainView.xaml,可以很好地绑定(bind)到 MainViewModel。
我想尝试的是将主窗体上的许多控件拆分为 UserControl。
现在,我将 UserControls 与 MainView 一起放入 Views 文件夹中,并将它们命名为 LeftSideControlView.xaml 和 RightSideControlView.xaml。对应的ViewModels在名为LeftSideControlViewModel等的ViewModels文件夹中。
我成功地将用户控件添加到主视图:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<UserControls:LeftSideControlView cal:Bind.Model="{Binding}" />
<UserControls:RightSideControlView cal:Bind.Model="{Binding}"
Grid.Column="1" />
</Grid>
它们在设计器中正确显示。这是 xaml 中的其中一个:
<UserControl x:Class="TwitterCaliburnWPF.Library.Views.LeftSideControlView"
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:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel>
<Label x:Name="Text" FontSize="25" HorizontalAlignment="Center" Margin="5"/>
<TextBox x:Name="TextBox1"
Width="200"
HorizontalAlignment="Center" FontSize="25" Margin="5" />
<Button Width="200" Height="50" Content="Button!" Margin="20" />
</StackPanel>
</Grid>
我使用 CaSTLe.Windsor 在 AppBootstrapper for Caliburn 中添加了 View 模型及其接口(interface)。
public class ApplicationContainer : WindsorContainer
{
public ApplicationContainer()
{
// Register all dependencies here
Register(
Component.For<IWindowManager>().ImplementedBy<WindowManager>().LifeStyle.Is(LifestyleType.Singleton),
Component.For<IEventAggregator>().ImplementedBy<EventAggregator>().LifeStyle.Is(LifestyleType.Singleton),
Component.For<ILeftSideControlViewModel>().ImplementedBy<LeftSideControlViewModel>(),
Component.For<IRightSideControlViewModel>().ImplementedBy<RightSideControlViewModel>()
);
RegisterViewModels();
}
private void RegisterViewModels()
{
Register(AllTypes.FromAssembly(GetType().Assembly)
.Where(x => x.Name.EndsWith("ViewModel"))
.Configure(x => x.LifeStyle.Is(LifestyleType.Transient)));
}
这是 LeftSideControlViewModel 类:
using Screen = Caliburn.Micro.Screen;
namespace TwitterCaliburnWPF.Library.ViewModels
{
public class LeftSideControlViewModel : Screen, ILeftSideControlViewModel
{
private string _text = "Hello from the Left side!";
private string _textBox1 = "Enter Text Here";
public string Text
{
get { return _text; }
}
public string TextBox1
{
get { return _textBox1; }
}
}
}
这是 MainViewModel,我将继续我在 Caliburn.Micro 文档中阅读的内容,就像我尝试之前一样,MainViewModel 中没有任何内容专门告诉它加载这 2 个控件或显示这 2 个控件。
当应用程序启动并运行时,这些值仍未绑定(bind)到各自 View 模型中的用户控件。
namespace TwitterCaliburnWPF.Library.ViewModels
{
public class MainViewModel : Conductor<IScreen>
{
public MainViewModel()
{
ShowLeftControl();
ShowRightControl();
}
private void ShowRightControl()
{
ActivateItem(new RightSideControlViewModel());
}
private void ShowLeftControl()
{
ActivateItem(new LeftSideControlViewModel());
}
public string TextToDisplay
{
get { return "Coming from the ViewModel!"; }
}
}
}
最佳答案
你不需要在这里使用Conductor
。这基本上用于导航场景。只需在 MainViewModel
上创建两个公共(public)属性,一个用于 RightSideControlViewModel
,称为 RightSide,另一个用于 LeftSideControlViewModel
,称为 LeftSide。然后,不要直接在 MainView 中实例化 UserControl,而是创建两个 ContentControls
,一个使用 x:Name="LeftSide"
,另一个使用 x:name= "RightSide"
这是一种 View 模型优先的实现方式。如果您想先查看,请将用户控件定义保留在您的 MainView 中,但更改 Bind.Model 以使其指向您创建的新属性,例如 Bind.Model="{Binding LeftSide}"
基本上,您拥有事物的方式定义了....绑定(bind)只是没有指向正确的对象,或多或少。你已经有了 Conductor,你不需要它来完成这个。如果您打算拥有某种导航架构,您可能希望保留它。请记住,当您在 Conductor 上调用 ActivateItem 时,您基本上是在更改其 ActiveItem 属性;一次只有一个模型处于事件状态。在上述情况下,您激活了两个项目,但只有第二个保持事件状态。此外,在您看来,没有任何内容绑定(bind)到 ActiveItem。
我希望这是有道理的!
关于c# - Caliburn.Micro 让它将 MainView 中的 UserControls 绑定(bind)到他们的 ViewModels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9997226/