开发者

Two dynamically assigned ContentControls in single view in Caliburn.Micro

开发者 https://www.devze.com 2023-03-23 23:29 出处:网络
I have a UserControl that contains two ContentControls that need to have different UserControl Views bound to them at runtime.The attached-Property solution noted here does not seem to work in Silverl

I have a UserControl that contains two ContentControls that need to have different UserControl Views bound to them at runtime. The attached-Property solution noted here does not seem to work in Silverlight. Or, I am doing something wrong. I also, found this, but it did not bring any joy either.

I had a single ContentControl working by naming it 'ActiveItem'. But, of course, I cannot have two ContentControls with the same name.

开发者_高级运维Thanks in advance for any help,

Jim


Just expose two public properties on your main view model, each one being an instance of the type of view model you wish to display. Then, in your view have a ContentControl with the corresponding name. E.g:

public class MyMainViewModel
{
  private NavigationViewModel navigation;
  private MyContentViewModel main;

  public MyMainViewModel()
  {
    // better to inject factories using constructor injection here
    this.Navigation = new NavigationViewModel();
    this.Main = new MyContentViewModel();
  }

  public NavigationViewModel Navigation
  {
    get { return navigation; }
    set { navigation= value; NotifyOfPropertyChanged(() => this.Navigation); }
  }

  public MyContentViewModel Main
  {
    get { return main; }
    set { main= value; NotifyOfPropertyChanged(() => this.Main); }
  }

  ...
}

<ContentControl x:Name="Navigation" />
...
<ContentControl x:Name="Main" />


This is an old question, but in case anyone is having the same issue, I post here my way of handling it from the beginning and in a more thorough manner:

  1. Your main window that contain both (or even more than two) of your User Controls must be inherited from Caliburn.Micro.Conductor<Screen>.Collection.AllActive;
  2. Your User Controls must be inherited from Caliburn.Micro.Screen;
  3. You must also keep naming conventions in mind. If you use MenuUC as the name of a ContentControl in your View, also create a property named MenuUC in your ViewModel;
  4. Initialize your UserControl as I do in Constructor;
  5. Now you can use ActivateItem(MenuUC) and DeactivateItem(MenuUC) everywhere in your code. Caliburn.Micro automatically detects which one you want to work with.

Example XAML View code:

<Window x:Class="YourProject.Views.YourView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="YourViewTitle" Width="900" Height="480">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="4*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Menu Side Bar -->
        <ContentControl Grid.Row="0" Grid.Column="0" x:Name="MenuUC" />

        <!-- Panel -->
        <Border Grid.Column="1" Grid.RowSpan="2" BorderThickness="1,0,0,0" BorderBrush="#FF707070" >
            <ContentControl x:Name="PanelUC" />
        </Border>
    </Grid>
</Window>

Example C# ViewModel code:

class YourViewModel : Conductor<Screen>.Collection.AllActive
{
    // Menu Side Bar
    private MenuUCViewModel _menuUC;
    public MenuUCViewModel MenuUC
    {
        get { return _menuUC; }
        set { _menuUC = value; NotifyOfPropertyChange(() => MenuUC); }
    }

    // Panel
    private Screen _panelUC;
    public Screen PanelUC
    {
        get { return _panelUC; }
        set { _panelUC = value; NotifyOfPropertyChange(() => PanelUC); }
    }

    // Constructor
    public YourViewModel()
    {
        MenuUC = new MenuUCViewModel();
        ActivateItem(MenuUC);

        PanelUC = new FirstPanelUCViewModel();
        ActivateItem(PanelUC);
    }

    // Some method that changes PanelUC (previously FirstPanelUCViewModel) to SecondPanelUCViewModel
    public void ChangePanels()
    {
        DeactivateItem(PanelUC);
        PanelUC = new SecondPanelUCViewModel();
        ActivateItem(PanelUC);
    }
}

In the above example, ChangePanels() acts as a method to load new User Control into your ContentControl.

Also read this question, it might be help you further.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号