[英]Caliburn.Micro getting it to bind UserControls in a MainView to their ViewModels
我有一个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!"; }
}
}
}
您不需要在这里使用Conductor
。 这基本上用于导航场景。 只是要两个公共属性您MainViewModel
一个RightSideControlViewModel
叫RightSide,一个用于LeftSideControlViewModel
,叫莱夫特赛德。 然后,不是直接在MainView中实例化UserControl,而是创建两个ContentControls
,一个用x:Name="LeftSide"
,另一个用x:name="RightSide"
这是一个视图模型第一种完成它的方法。 如果您想先查看视图,请在MainView中保留用户控件定义,但更改Bind.Model以使其指向您创建的新属性,如Bind.Model="{Binding LeftSide}"
基本上,你有事物的方式定义....绑定只是或多或少指向正确的对象。 你有导体在那里,你不需要完成这个。 如果您打算使用某种导航架构,可能需要保留它。 请记住,当您在Conductor上调用ActivateItem时,您基本上正在更改其ActiveItem属性; 只有一个模型一次处于活动状态。 在上面的情况下,您激活两个项目,但只有第二个项目保持活动状态。 此外,在您的视图中,ActiveItem没有任何约束。
我希望这是有道理的!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.