Два динамически назначаемых элемента управления ContentControl в одном представлении в Caliburn.Micro

У меня есть UserControl, содержащий два ContentControl, которые должны иметь разные представления UserControl, привязанные к ним во время выполнения. Решение с прикрепленным свойством, отмеченное здесь, действительно похоже, не работает в Silverlight. Или я что-то делаю не так. Я также нашел это, но и радости это не принесло.

У меня работал один ContentControl, назвав его ActiveItem. Но, конечно, у меня не может быть двух ContentControl с одинаковым именем.

Заранее благодарю за любую помощь,

Джим


person Jim Reineri    schedule 31.07.2011    source источник
comment
Разместите свою модель просмотра и просмотрите.   -  person Derek Beattie    schedule 01.08.2011
comment
Пример, представленный в ответе, в значительной степени покрывает это. Спасибо   -  person Jim Reineri    schedule 01.08.2011


Ответы (2)


Просто предоставьте два общедоступных свойства в своей основной модели представления, каждое из которых является экземпляром того типа модели, который вы хотите отобразить. Тогда, по вашему мнению, есть ContentControl с соответствующим именем. Например:

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" />
person devdigital    schedule 01.08.2011
comment
Спасибо. Кажется, это слишком просто. - person Jim Reineri; 01.08.2011

Это старый вопрос, но на случай, если у кого-то возникнет такая же проблема, я публикую здесь свой способ справиться с ней с самого начала и более тщательно:

  1. Главное окно, которое содержит оба (или даже более двух) ваших пользовательских элементов управления, должно быть унаследовано от Caliburn.Micro.Conductor<Screen>.Collection.AllActive;
  2. Ваши пользовательские элементы управления должны быть унаследованы от Caliburn.Micro.Screen;
  3. Вы также должны помнить об именах. Если вы используете MenuUC в качестве имени ContentControl в вашем представлении, также создайте свойство с именем MenuUC в вашей ViewModel;
  4. Инициализируйте свой UserControl, как я в конструкторе;
  5. Теперь вы можете использовать ActivateItem(MenuUC) и DeactivateItem(MenuUC) везде в своем коде. Caliburn.Micro автоматически определяет, с каким из них вы хотите работать.

Пример кода просмотра XAML:

<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>

Пример кода C # ViewModel:

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);
    }
}

В приведенном выше примере ChangePanels() действует как метод загрузки нового пользовательского элемента управления в ваш ContentControl.

Также прочтите этот вопрос, возможно, это поможет вам в дальнейшем.

person Amir Maleki    schedule 30.05.2020