简体   繁体   English

在 UserControl WPF MVVM caliburn 内的 UserControl 之间切换

[英]Switch between UserControls inside UserControl WPF MVVM caliburn

I need to navigate from one usercontrol to another with a button click, and i'm using two different approaches.我需要通过单击按钮从一个用户控件导航到另一个,并且我使用了两种不同的方法。 在此处输入图像描述

Approach 1: I have a main window with some buttons that will select my "parent" user control view model, using the Navigation Controller.方法 1:我有一个主 window 和一些按钮,这些按钮将 select 我的“父”用户控制视图 model,使用导航 Z9BBF37CF30237

    public NavigationController(MainWindowViewModel viewModel)
    {
        this.viewModel = viewModel;
    }

    public void Execute(object parameter)
    {
        string par = parameter.ToString();

        switch (par)
        {
            case "0":
                viewModel.SelectedViewModel = new ViewModel1();
                break;

            case "1":
                viewModel.SelectedViewModel = new ViewModel2();
                break;
        }
    }

XAML side (...) XAML 侧(...)

  <Button Command="{Binding NavigationController}" CommandParameter="1" />
  <ContentControl Content="{Binding SelectedViewModel}" />

So far so good, and I believe this is a good tactic.到目前为止一切都很好,我相信这是一个很好的策略。 But for Approach 2, where I have the proper "parent" user control selected, the button click is bound in a different way: XAML但是对于方法 2,我选择了正确的“父”用户控件,按钮单击以不同的方式绑定:XAML

    <Button cal:Message.Attach="ShowUserControl3()"/>

VM虚拟机

    public object SelectedActionViewModel
    {
        get => _selectedActionViewModel;
        set
        {
            _selectedActionViewModel = value;
        }
    }

    public void ShowUserControl3()
    {
        _selectedActionViewModel = new VMusercontrol3();
        OnPropertyChanged(nameof(SelectedActionViewModel));
    }

And this second approach works fine.. on the first or second time i click the button.第二种方法效果很好..在我第一次或第二次单击按钮时。 After that, the OnPropertyChanged keeps passing null and won't select the proper user control anymore.之后, OnPropertyChanged继续通过 null 并且不会 select 不再是正确的用户控制。 What am i missing here?我在这里想念什么?

Extra question: how can I select UserControl3 from UserControl4?额外的问题:我如何从 UserControl4 获得 select UserControl3?

Edit: All of the user controls inherit from a BaseViewModel, and that is where things are weird, because the propertyChanged is null编辑:所有用户控件都继承自 BaseViewModel,这就是奇怪的地方,因为 propertyChanged 是 null

public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public event EventHandler ClosingRequest;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

I hope I understood your question correctly.我希望我正确理解了你的问题。 An easier way to accomplish this would be to use the in-build support of Caliburn Micro.实现这一点的更简单方法是使用 Caliburn Micro 的内置支持。 For example, modifying your shell view model as例如,将您的 shell 视图 model 修改为

public class ShellViewModel:Conductor<object>  // Replace object with your base viewmodel if any
{

        private UserControl1ViewModel _uc1Instance;
        public UserControl1ViewModel UC1Instance => _uc1Instance ?? (_uc1Instance = new UserControl1ViewModel());

        private UserControl2ViewModel _uc2Instance;
        public UserControl2ViewModel UC2Instance => _uc2Instance ?? (_uc2Instance = new UserControl2ViewModel());


        public void ActivateUserControl1()
        {
            ActivateItem(UC1Instance);
        }

        public void ActivateUserControl2()
        {
            ActivateItem(UC2Instance);
        }
}

The Conductor<T> class from Caliburn Micro enables you to handle multiple screens(Views) with only one active. Caliburn Micro 的Conductor<T> class 使您能够处理多个屏幕(视图),并且只有一个处于活动状态。 You could now change your views as您现在可以将您的观点更改为

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <StackPanel Orientation="Vertical">
            <Button x:Name="ActivateUserControl1" Content="Show UC 1"/>
            <Button x:Name="ActivateUserControl2" Content="Show UC 2"/>
        </StackPanel>

        <ContentControl Grid.Column="1" x:Name="ActiveItem"/>
    </Grid>

The same process could be repeated in your UserControl1 and UserControl2 for achieving Options to set UserControl3 and UserControl4.可以在您的 UserControl1 和 UserControl2 中重复相同的过程,以实现设置 UserControl3 和 UserControl4 的选项。

Regarding your second question, which was about communicating between UserControl3 and UserControl4, you could make use of EventAggregators .关于您的第二个问题,即关于 UserControl3 和 UserControl4 之间的通信,您可以使用EventAggregators

You can find a sample of EventAggregator in here .您可以在此处找到 EventAggregator 的示例。

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

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