【问题标题】:UWP conventions with Caliburn.Micro使用 Caliburn.Micro 的 UWP 约定
【发布时间】:2015-11-19 09:05:50
【问题描述】:

我创建了一个示例 UWP 项目,并基于 this tutorial 添加了 Caliburn.Micro 3.0 beta1。

使用 SplitView,我可以在按下窗格按钮时添加一个新的 ViewModel:

ShellView

 <Button x:Name="OpenSecondView"
         Margin="24"
         Content="My Second View" />

ShellViewModel

public void OpenSecondView()
{
  _navigationService.For<MainViewModel>().Navigate();
}

它会加载正确的视图(所以我想,约定是有效的)。

我在详细视图中有一个按钮,它设置了 Name 属性。

主视图

<Button Name="btnStartAction"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        RelativePanel.AlignHorizontalCenterWithPanel="True"
        RelativePanel.Below="btnInformation"
        Style="{StaticResource button}">

我在 ViewModel 中添加了一个同名的方法。

MainViewModel

public void btnStartAction()
{
  var x = 2;
}

不幸的是,当我点击它时,什么也没有发生。

我应该设置什么?

更新

嗯,发生了一些奇怪的事情。

如果我在 MainView.xaml.cs 中添加以下行,按钮将起作用:

public MainView()
{
   this.InitializeComponent();
   this.DataContext = new MainViewModel();
}

所以,看来 ViewModel 可以找到它的 View(因此我可以看到它)但是 View 没有 DataContext。

我该怎么办?

更新 2

这就是注册框架的方式。

XAML

 <SplitView.Content>
                <Grid>                  
                <Frame Grid.Row="1"
                           DataContext="{x:Null}"
                           cm:Message.Attach="[Event Loaded] = [SetupNavigationService($source)]" />
                </Grid>
  </SplitView.Content>

ShellModelView

public ShellViewModel(WinRTContainer container)
{
  _container = container;      
}

public void SetupNavigationService(Frame frame)
{
  _navigationService = _container.RegisterNavigationService(frame);
}

【问题讨论】:

    标签: c# caliburn.micro uwp


    【解决方案1】:

    Caliburn Micro 约定功能使用 x:Name 指令而不是 Name 属性。

    <Button x:Name="btnStartAction"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        RelativePanel.AlignHorizontalCenterWithPanel="True"
        RelativePanel.Below="btnInformation"
        Style="{StaticResource button}">
    

    更新

    抱歉提供错误信息,Name 和 x:Name 都可以用于约定。

    您应该将MainViewModel 注册到WinRTContainer

    App.xaml.cs

    public sealed partial class App
    {
      private WinRTContainer _container;
    
      protected override void Configure()
      {
         _container = new WinRTContainer();
         _container.RegisterWinRTServices();
    
         _container
              .PerRequest<ShellViewModel>()
              .PerRequest<MyFirstViewModel>()
              .PerRequest<MySecondViewModel>()
              .PerRequest<MyThirdViewModel>()
              .PerRequest<MainViewModel>();
    
         var navigationManager = SystemNavigationManager.GetForCurrentView();
    
         navigationManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
    
      }
    }
    

    有关简单容器的更多信息,请参阅Simple IoC Container

    【讨论】:

    • 我都尝试了(x:Name 和 Name),如果我不设置 DataContext,它们将不起作用。
    • @Nestor 很遗憾听到这个消息,ViewModelBinder 似乎没有将 View 的 DataContext 设置为 ViewModel。我已经尝试添加自定义 ViewModel/View,如果我不将自定义 ViewModel 注册到 WinRTContainer(在后面的 App.xaml 代码中的 Configure 方法),则操作绑定不起作用,那么您是否将 MainViewModel 注册到 WinRTContainer?顺便说一句,名称也适用于约定,抱歉给你错误的信息 XD
    • 我应该如何在 WinRTContainer 中注册我的 ViewModel? XAML 具有 RegisterNavigationService 的绑定,如下所示:&lt;Frame Grid.Row="1" DataContext="{x:Null}" cm:Message.Attach="[Event Loaded] = [SetupNavigationService($source)]" /&gt;。我还应该设置什么?
    • @Nestor 我已经更新了答案,希望你能成功。
    • 是的,那是缺失的部分。它现在可以在没有显式初始化的情况下工作。谢谢,我接受你的回答。
    【解决方案2】:

    请注意,如果您决定实施需要缓存视图模型以供以后恢复的挂起和恢复操作,则可能会出现与 ShellView 和 Window.Current.Contents 被错误设置为恢复视图而不是ShellView 页面。正在解决此问题。

    【讨论】:

    • 那么建议的解决方案是什么?
    • 目前还没有。目前作为一种潜在的解决方法在桌面上检查 Window.Current.Content 是否已设置(不为空),然后找出某种方法来重新初始化 Frame。它未经测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多