我有一个MainView.xaml,绑定到MainViewModel就好了。
我想尝试的是将我在主窗体上的许多控件拆分为UserControls。
现在,我将UserControls与MainView一起放在Views文件夹中,并命名为LeftSideControlView.xaml和RightSideControlView.xaml。相应的ViewModel位于ViewModels文件夹中,名为LeftSideControlViewModel等。
我成功将usercontrols添加到主视图中:
<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中添加了viewmodels及其接口。
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中没有任何内容告诉它加载这两个控件或显示这两个控件。
当应用程序启动并运行时,值仍未绑定到各自视图模型中的用户控件。
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!"; }
}
}
}
答案 0 :(得分:23)
您无需在此处使用Conductor
。这基本上用于导航场景。只需在MainViewModel
上为RightSideControlViewModel
创建两个名为RightSide的公共属性,为LeftSideControlViewModel
创建一个名为LeftSide的公共属性。然后,不是直接在MainView中实例化UserControl,而是创建两个ContentControls
,一个x:Name="LeftSide"
,另一个x:name="RightSide"
这是视图模型第一种完成它的方法。如果您想先查看,请在MainView中保留用户控件定义,但更改Bind.Model以使其指向您创建的新属性,如Bind.Model="{Binding LeftSide}"
基本上,你有事物的方式定义....绑定只是没有指向正确的对象,或多或少。你有导体在那里,你不需要完成这个。如果您打算使用某种导航架构,可能需要保留它。请记住,当您在Conductor上调用ActivateItem时,您基本上正在更改其ActiveItem属性;只有一个模型一次处于活动状态。在上面的情况下,您激活两个项目,但只有第二个项目保持活动状态。此外,在您的视图中,ActiveItem没有任何约束。
我希望这是有道理的!