简体   繁体   English

Caliburn.Micro将它绑定到MainView中的UserControls到他们的ViewModels

[英]Caliburn.Micro getting it to bind UserControls in a MainView to their ViewModels

I have a MainView.xaml, binding to a MainViewModel just fine. 我有一个MainView.xaml,绑定到MainViewModel就好了。

What I wanted to try out was splitting a lot of controls I have on my main form into UserControls. 我想尝试的是将我在主窗体上的许多控件分成UserControls。

Now I put the UserControls inside the Views folder along with the MainView and named them, LeftSideControlView.xaml and RightSideControlView.xaml. 现在我将UserControls与MainView一起放在Views文件夹中,并命名为LeftSideControlView.xaml和RightSideControlView.xaml。 The corresponding ViewModels are in the ViewModels folder called LeftSideControlViewModel, etc. 相应的ViewModel位于ViewModels文件夹中,名为LeftSideControlViewModel等。

I successfully added the usercontrols to the mainview: 我成功将usercontrols添加到主视图:

 <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <UserControls:LeftSideControlView cal:Bind.Model="{Binding}" />
    <UserControls:RightSideControlView cal:Bind.Model="{Binding}"
                                  Grid.Column="1" />
</Grid>

they show up correctly in the designer. 它们在设计师中正确显示。 Here's one of them in xaml: 这是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>

I added the viewmodels and their interfaces inside the AppBootstrapper for Caliburn using Castle.Windsor. 我使用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)));
  }

Here's the LeftSideControlViewModel class: 这是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; }
       }
    }
 }

Here's the MainViewModel and I'm going off what I read in the Caliburn.Micro documention, as before I tried this nothing was specifically in the MainViewModel to tell it to load these 2 controls or show these 2 controls. 这是MainViewModel,我正在阅读我在Caliburn.Micro文档中读到的内容,就像之前我尝试过的那样,MainViewModel中没有任何内容告诉它加载这两个控件或显示这两个控件。

Still when the app is up and running the values are not binding to the usercontrols from their respective viewmodels. 仍然当应用程序启动并运行时,值不会绑定到各自视图模型中的用户控件。

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!"; }
      }
   }
}

You don't need to use a Conductor here. 您不需要在这里使用Conductor That's basically used for navigation scenarios. 这基本上用于导航场景。 Just make two public properties on your MainViewModel one for RightSideControlViewModel called RightSide and one for LeftSideControlViewModel , called LeftSide. 只是要两个公共属性您MainViewModel一个RightSideControlViewModel叫RightSide,一个用于LeftSideControlViewModel ,叫莱夫特赛德。 Then, instead of instantiating your UserControls directly in your MainView, create two ContentControls , one with x:Name="LeftSide" and the other with x:name="RightSide" This is a view-model-first way of accomplishing it. 然后,不是直接在MainView中实例化UserControl,而是创建两个ContentControls ,一个用x:Name="LeftSide" ,另一个用x:name="RightSide"这是一个视图模型第一种完成它的方法。 If you want to do it view-first, keep the user control definitions in your MainView, but change the Bind.Model so that it points to the new properties you created, like Bind.Model="{Binding LeftSide}" 如果您想先查看视图,请在MainView中保留用户控件定义,但更改Bind.Model以使其指向您创建的新属性,如Bind.Model="{Binding LeftSide}"

Basically, the way you have things defines....the bindings just aren't pointing at the right objects, more or less. 基本上,你有事物的方式定义....绑定只是或多或少指向正确的对象。 You've got the Conductor in there, which you don't need to accomplish this. 你有导体在那里,你不需要完成这个。 You may want to keep it if you intend to have some sort of navigation architecture. 如果您打算使用某种导航架构,可能需要保留它。 Remember that when you call ActivateItem on a Conductor, you are basically changing its ActiveItem property; 请记住,当您在Conductor上调用ActivateItem时,您基本上正在更改其ActiveItem属性; only one model with be active at a time. 只有一个模型一次处于活动状态。 In the case above you activate both items, but only the second one remains active. 在上面的情况下,您激活两个项目,但只有第二个项目保持活动状态。 Furthermore, in your view, nothing is bound to ActiveItem. 此外,在您的视图中,ActiveItem没有任何约束。

I hope this makes sense! 我希望这是有道理的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM