WPF Caliburn.Микро и DXTabControl с UserControl не работают

#c# #wpf #mvvm #tabcontrol #caliburn.micro

#c# #wpf #mvvm #tabcontrol #caliburn.micro

Вопрос:

Я пытаюсь использовать TabControl для переключения между UserControls.

Я мог бы просто установить содержимое вкладок в usercontrols с помощью XAML, но тогда оно будет привязано только к view, а не к viewmodel.

Моя виртуальная машина — это Caliburn.Микро проводник и он вызывает ActivateItem всякий раз, когда пользователь переключает вкладки. Он работал нормально, когда у меня был только один usercontrol, но когда я создал другой, первый не загрузит представление.

Вот часть кода, который я использую:

ShellView:

 <dx:ThemedWindow x:Class="PSCServiceManager.Views.ShellView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cal="http://www.caliburnproject.org"
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             Title="Service Manager" WindowState="Maximized"
             Height="525" Width="720">

<Grid>
    <dx:DXTabControl>
        <dx:DXTabItem Header="Master Teknisi">
            <ContentControl x:Name="LoadMasterTechnicianView" cal:View.Model="{Binding ActiveItem}" />
        </dx:DXTabItem>

        <dx:DXTabItem Header="Servisan">
            <ContentControl x:Name="LoadServicesView" cal:View.Model="{Binding ActiveItem}" />
        </dx:DXTabItem>
    </dx:DXTabControl>
</Grid>
 

ShellViewModel:

 using Caliburn.Micro;

namespace PSCServiceManager.ViewModels
{
    public class ShellViewModel : Conductor<IScreen>
    {
        private MasterTechnicianViewModel masterTechnicianViewModel;
        private ServicesViewModel servicesViewModel;

        public ShellViewModel()
        {
            LoadMasterTechnicianView();
        }

        public void LoadMasterTechnicianView()
        {
            ActivateItem(masterTechnicianViewModel);
        }

        public void LoadServicesView()
        {
            ActivateItem(servicesViewModel);
        }
    }
}
 

Ответ №1:

Более простым / альтернативным способом реализации этого было бы создать коллекцию пользовательских элементов управления, которые вы хотели бы привязать к элементу управления Tab. Например,

 public interface ITabUserControl
{
    string DisplayName { get; set; }
}

public class MasterTechnicianViewModel : ITabUserControl
{
    public string DisplayName { get; set; } = "Master Technician";
}

public class ServicesViewModel : ITabUserControl
{
    public string DisplayName { get; set; } = "Services";
}
 

Теперь в вашей ShellViewModel вы можете создать коллекцию ITabUserControl

 public List<ITabUserControl> UserControls { get; set; }
    public ShellViewModel()
    {
        UserControls = new List<ITabUserControl>();
        UserControls.Add(new MasterTechnicianViewModel());
        UserControls.Add(new ServicesViewModel());
    }
 

И свяжите ваш TabControl как

  <dx:DXTabControl x:Name="UserControls"/>
 

Теперь вы можете переключаться между элементами управления без каких-либо проблем, не активируя его явно.