Caliburn.Micro如何将UserControls与MainView中的ViewModel进行绑定

14
我有一个名为MainView.xaml的文件,很好地绑定了MainViewModel。我想尝试的是将主窗体上的许多控件分割成用户控件。现在我将用户控件放入Views文件夹中,与MainView一起,并将它们命名为LeftSideControlView.xaml和RightSideControlView.xaml。相应的ViewModel位于ViewModels文件夹中,分别称为LeftSideControlViewModel等等。我成功地将用户控件添加到了主视图中。
 <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为Caliburn添加ViewModels及其接口时将它们放在了AppBootstrapper内。

 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!"; }
      }
   }
}
1个回答

25

在这里不需要使用Conductor。那基本上是用于导航场景。只需在您的MainViewModel上创建两个公共属性,一个用于名为RightSideControlViewModelRightSide和一个用于名为LeftSideControlViewModelLeftSide。然后,不要直接在MainView中实例化您的用户控件,而是创建两个ContentControls,其中一个使用x:Name="LeftSide",另一个使用x:name="RightSide"。这是一种以视图模型为先的方式来完成它。如果您想采用视图为先的方法,请将用户控件定义保留在MainView中,但更改Bind.Model,以便它指向您创建的新属性,如Bind.Model="{Binding LeftSide}"

基本上,您拥有的方式定义了......绑定仅仅没有指向正确的对象。您已经将Conductor放入其中,但您不需要它来完成此操作。如果您打算具有某种导航架构,则可能希望保留它。请记住,当您对Conductor调用ActivateItem时,您基本上正在更改其ActiveItem属性;每次只有一个模型处于活动状态。在上述情况下,您会激活这两个项目,但仅第二个项目保持活动状态。此外,在您的视图中,没有任何内容绑定到ActiveItem。

我希望这讲得通!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接