added SendReceiveViewModel and according View,

moved StartupHelpers to new Common project,
added TabControl to ShellView
master
Jonas Arnold 3 years ago
parent d152bf121d
commit c3a965875f
  1. 13
      Common/Common.csproj
  2. 24
      Common/StartupHelpers/AbstractFactory.cs
  3. 6
      Common/StartupHelpers/IAbstractFactory.cs
  4. 22
      Common/StartupHelpers/ServiceExtensions.cs
  5. 4
      MultiTerm.Core/MultiTerm.Core.csproj
  6. 8
      MultiTerm.Core/ViewModel/ITerminalViewModel.cs
  7. 10
      MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
  8. 31
      MultiTerm.Core/ViewModel/ShellViewModel.cs
  9. 8
      MultiTerm.Core/ViewModel/TerminalViewModel.cs
  10. 4
      MultiTerm.Wpf/App.xaml.cs
  11. 1
      MultiTerm.Wpf/MultiTerm.Wpf.csproj
  12. 12
      MultiTerm.Wpf/View/SendReceiveView.xaml
  13. 11
      MultiTerm.Wpf/View/SendReceiveView.xaml.cs
  14. 21
      MultiTerm.Wpf/View/ShellView.xaml
  15. 10
      MultiTerm.sln

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup>
</Project>

@ -0,0 +1,24 @@
namespace Common.StartupHelpers;
public class AbstractFactory<T> : IAbstractFactory<T>
{
private readonly Func<T> factory;
/// <summary>
/// Constructor for Abstract Factory.
/// </summary>
/// <param name="factory">Function of the factory</param>
public AbstractFactory(Func<T> factory)
{
this.factory = factory;
}
/// <summary>
/// Executes factory function and returns it.
/// </summary>
/// <returns>Factory</returns>
public T Create()
{
return factory();
}
}

@ -0,0 +1,6 @@
namespace Common.StartupHelpers;
public interface IAbstractFactory<T>
{
T Create();
}

@ -0,0 +1,22 @@
using Microsoft.Extensions.DependencyInjection;
namespace Common.StartupHelpers;
public static class ServiceExtensions
{
/// <summary>
/// Adds a factory for subcontrols to be created.
/// For example a UserControl can be instanciated using this Service.
/// </summary>
/// <typeparam name="TSubControl">type of the subcontrol</typeparam>
/// <param name="services">existing service collection</param>
public static void AddSubControlFactory<TSubControl>(this IServiceCollection services) where TSubControl : class
{
// add to DI: the subcontrol itself
services.AddTransient<TSubControl>();
// add to DI: Func of that subcontrol, that will create the subcontrol
services.AddSingleton<Func<TSubControl>>(x => () => x.GetService<TSubControl>()!);
// add to DI: Factory for the subcontrol
services.AddSingleton<IAbstractFactory<TSubControl>, AbstractFactory<TSubControl>>();
}
}

@ -14,4 +14,8 @@
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,8 @@
using System;
namespace MultiTerm.Core.ViewModel;
public interface ITerminalViewModel
{
string Title { get; }
}

@ -0,0 +1,10 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
namespace MultiTerm.Core.ViewModel;
[ObservableObject]
public partial class SendReceiveViewModel : TerminalViewModel
{
public override string Title => "SendReceive Tab";
}

@ -1,9 +1,38 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Common.StartupHelpers;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
namespace MultiTerm.Core.ViewModel;
public partial class ShellViewModel : ObservableObject
{
private readonly IAbstractFactory<SendReceiveViewModel> sendReceiveViewModelFactory;
[ObservableProperty]
private string title = "ShellView Test";
[ObservableProperty]
private ObservableCollection<ITerminalViewModel> terminalViewModels = new();
[ObservableProperty]
private ITerminalViewModel? selectedTerminalViewModel;
public ShellViewModel(IAbstractFactory<SendReceiveViewModel> sendReceiveViewModelFactory)
{
this.sendReceiveViewModelFactory = sendReceiveViewModelFactory;
// create a new terminal
this.AppendTerminal(this.sendReceiveViewModelFactory.Create());
}
public void AppendTerminal(ITerminalViewModel newTerminal)
{
// guard null value
if(newTerminal == null)
{
return;
}
// add to collection and set as selected
this.TerminalViewModels.Add(newTerminal);
this.SelectedTerminalViewModel = newTerminal;
}
}

@ -0,0 +1,8 @@
using System;
namespace MultiTerm.Core.ViewModel;
public abstract class TerminalViewModel : ITerminalViewModel
{
public abstract string Title { get; }
}

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MultiTerm.Core.ViewModel;
using Common.StartupHelpers;
using System.Windows;
namespace MultiTerm.Wpf;
@ -19,6 +20,9 @@ public partial class App : Application
// viewmodels
services.AddSingleton<ShellViewModel>();
// subcontrols
services.AddSubControlFactory<SendReceiveViewModel>();
})
.Build();
}

@ -13,6 +13,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\MultiTerm.Core\MultiTerm.Core.csproj" />
</ItemGroup>

@ -0,0 +1,12 @@
<UserControl x:Class="MultiTerm.Wpf.View.SendReceiveView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MultiTerm.Wpf.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</UserControl>

@ -0,0 +1,11 @@
using System.Windows.Controls;
namespace MultiTerm.Wpf.View;
public partial class SendReceiveView : UserControl
{
public SendReceiveView()
{
InitializeComponent();
}
}

@ -4,9 +4,28 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MultiTerm.Wpf.View"
xmlns:vm="clr-namespace:MultiTerm.Core.ViewModel;assembly=MultiTerm.Core"
xmlns:v="clr-namespace:MultiTerm.Wpf.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label Content="{Binding Title}"/>
<TabControl
x:Name="terminalTabControl"
ItemsSource="{Binding TerminalViewModels}"
SelectedItem="{Binding SelectedTerminalViewModel}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type vm:SendReceiveViewModel}">
<v:SendReceiveView/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Grid>
</UserControl>

@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33424.131
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTerm.Wpf", "MultiTerm.Wpf\MultiTerm.Wpf.csproj", "{1C18608F-596A-47ED-9BD6-96E5E52E6E88}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiTerm.Wpf", "MultiTerm.Wpf\MultiTerm.Wpf.csproj", "{1C18608F-596A-47ED-9BD6-96E5E52E6E88}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTerm.Core", "MultiTerm.Core\MultiTerm.Core.csproj", "{A4ED5CBB-954E-4F23-B9CB-8E30DF7B8F48}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiTerm.Core", "MultiTerm.Core\MultiTerm.Core.csproj", "{A4ED5CBB-954E-4F23-B9CB-8E30DF7B8F48}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{26454190-1B60-46BE-8234-3207FB00D8A4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -21,6 +23,10 @@ Global
{A4ED5CBB-954E-4F23-B9CB-8E30DF7B8F48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4ED5CBB-954E-4F23-B9CB-8E30DF7B8F48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4ED5CBB-954E-4F23-B9CB-8E30DF7B8F48}.Release|Any CPU.Build.0 = Release|Any CPU
{26454190-1B60-46BE-8234-3207FB00D8A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26454190-1B60-46BE-8234-3207FB00D8A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26454190-1B60-46BE-8234-3207FB00D8A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26454190-1B60-46BE-8234-3207FB00D8A4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Loading…
Cancel
Save