I am trying to set up my application to show a different view depending on what the name of the device is. Unfortunately, I can't seem to get the View to load, though the ViewModel is getting called. I'm not entirely sure what I'm missing.
Currently, when the application loads, the only thing shows up is the MainWindow, but the View is not being loaded inside of it.
How can I get a View to load?
Here is my MainWindow.axaml:
<Window
xmlns="https://github.com/avaloniaui"
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"
xmlns:vm="clr-namespace:TAStagingApp.ViewModels.Implementations;assembly=TAStagingApp.ViewModels"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
x:Class="TAStagingApp.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Background="{StaticResource TABackgroundColor}"
Icon="/Assets/tastaging.png"
WindowStartupLocation="CenterScreen"
Title="TA Staging">
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<Grid>
<ContentPresenter Name="StagingContent"/>
</Grid>
</Window>
And the MainWindow.axaml.cs
namespace TAStagingApp.Views;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public void SetContent(Control control)
{
var mainContent = this.FindControl<ContentPresenter>("StagingContent");
mainContent!.Content = control;
}
}
App.axaml.cs
using AvaloniaApplication = Avalonia.Application;
namespace TAStagingApp;
public partial class App : AvaloniaApplication
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
var viewModelLoader = new ViewModelLoader(new MainWindow());
ServiceLocator.Initialize(viewModelLoader);
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
DataContext = GetRequiredService<IMainWindowViewModel>();
desktop.MainWindow = new MainWindow
{
DataContext = DataContext,
};
viewModelLoader.LoadContentViewBasedOnComputerName();
}
base.OnFrameworkInitializationCompleted();
}
private static T GetRequiredService<T>() => Locator.Current.GetRequiredService<T>();
}
ViewModelLoader.cs
namespace TAStagingApp.DependencyInjection.Loaders;
public sealed class ViewModelLoader(MainWindow mainWindow) : IViewModelLoader
{
private readonly MainWindow _mainWindow = mainWindow;
public void LoadContentViewBasedOnComputerName()
{
var serviceProvider = DeviceTypeHelper.GetDeviceTypeServiceProvider();
var deviceType = DeviceTypeHelper.GetDeviceType(serviceProvider);
Control contentView = deviceType.Value.ToString() switch
{
var device when device.Equals(DeviceType.Server.ToString()) => new ServerConfigureView(),
var device when device.Equals(DeviceType.Terminal.ToString()) => new TerminalConfigureView(),
var device when device.Equals(DeviceType.Kitchen.ToString()) => new TerminalConfigureView(),
_ => new AdminView()
};
_mainWindow.SetContent(contentView);
}
}
MainWindowViewModel.cs
namespace TAStagingApp.ViewModels.Implementations;
public class MainWindowViewModel : ViewModelBase, IMainWindowViewModel
{
public MainWindowViewModel(IActivateViewModel viewModel)
{
if (viewModel.GetType() == typeof(TerminalConfigureViewModel))
{
TerminalConfigureViewModel = viewModel;
}
else if (viewModel.GetType() == typeof(ServerConfigureViewModel))
{
ServerConfigureViewModel = viewModel;
}
else
{
AdminViewModel = viewModel;
}
Activate(viewModel);
}
public MainWindowViewModel()
{
}
public IActivateViewModel AdminViewModel { get; } = default!;
public IActivateViewModel TerminalConfigureViewModel { get; } = default!;
public IActivateViewModel ServerConfigureViewModel { get; } = default!;
private static void Activate(IActivateViewModel viewModel)
=> viewModel.Activate();
}
I've been looking at this for two days now and can't figure out what I'm missing.
The problem is your
ViewModelLoader
is working with an instance ofMainWindow
which is different from the actualyou can fix it by instantiating
ViewModelLoader
with the application Main windowSide Advice
Actually, you should redesign your architecture because you get architecture dead look!
If I were you, I will use data templates to make my life easy!
And put in your
MainViewModle
Property CalledCurrentViewModel
orActivatedViewModel
or Whatever of typeViewModelBase
All of
ServerConfigureViewModel
,TerminalConfigureViewModel
andAdminViewModel
should inherit fromViewModelBase
and can be signed toCurrentViewModdel
and bind to it in main Window
now if you change
CurrentViewModdel
in Main Window View will change without all this code ofViewModleLocator
and this staff