implemented tab closing

master
Jonas Arnold 3 years ago
parent 2daa9c2027
commit 63946ad478
  1. 17
      MultiTerm.Core/ViewModel/ITerminalViewModel.cs
  2. 7
      MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
  3. 24
      MultiTerm.Core/ViewModel/ShellViewModel.cs
  4. 23
      MultiTerm.Core/ViewModel/TerminalViewModel.cs
  5. 29
      MultiTerm.Wpf/View/ShellView.xaml

@ -1,8 +1,19 @@
using System; namespace MultiTerm.Core.ViewModel;
namespace MultiTerm.Core.ViewModel;
public interface ITerminalViewModel public interface ITerminalViewModel
{ {
/// <summary>
/// Title of the Terminal View.
/// </summary>
string Title { get; } string Title { get; }
/// <summary>
/// Request Closing of Terminal.
/// </summary>
void CloseRequest();
/// <summary>
/// Closing of Terminal was initiated.
/// </summary>
event EventHandler ClosingEvent;
} }

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

@ -39,15 +39,29 @@ public partial class ShellViewModel : ObservableObject
public void AppendTerminal(ITerminalViewModel newTerminal) public void AppendTerminal(ITerminalViewModel newTerminal)
{ {
// guard null value // guard null value
if(newTerminal == null) if(newTerminal == null) { return; }
{
return; // add to collection and register closing event handler
}
// add to collection and set as selected
this.TerminalViewModels.Add(newTerminal); this.TerminalViewModels.Add(newTerminal);
newTerminal.ClosingEvent += Terminal_ClosingEvent;
// set as selected
this.SelectedTerminalViewModel = newTerminal; this.SelectedTerminalViewModel = newTerminal;
} }
private void Terminal_ClosingEvent(object? sender, EventArgs e)
{
if(sender is not ITerminalViewModel tvm) { throw new ArgumentException(nameof(sender)); }
this.RemoveTerminal(tvm);
}
public void RemoveTerminal(ITerminalViewModel terminalToRemove)
{
// guard null value
if(terminalToRemove == null) { return; }
this.TerminalViewModels.Remove(terminalToRemove);
}
partial void OnDefaultReceiveNewlineSeparatorChanged(NewlineSeparatorType value) partial void OnDefaultReceiveNewlineSeparatorChanged(NewlineSeparatorType value)
{ {
Console.WriteLine($"Changed to {value}"); Console.WriteLine($"Changed to {value}");

@ -1,8 +1,27 @@
using System; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace MultiTerm.Core.ViewModel; namespace MultiTerm.Core.ViewModel;
public abstract class TerminalViewModel : ITerminalViewModel public abstract partial class TerminalViewModel : ObservableObject, ITerminalViewModel
{ {
public abstract string Title { get; } public abstract string Title { get; }
public event EventHandler? ClosingEvent;
/// <summary>
/// Method to override if any closing actions are required.
/// Closing can be cancelled using the return value.
/// </summary>
/// <returns>true if closing is allowed. false if it shall be cancelled.</returns>
protected virtual bool ClosingActions() { return true; }
[RelayCommand]
public void CloseRequest()
{
if (this.ClosingActions() == true)
{
ClosingEvent?.Invoke(this, EventArgs.Empty);
}
}
} }

@ -57,23 +57,36 @@
<MenuItem Header="_View"/> <MenuItem Header="_View"/>
<MenuItem Header="_About"/> <MenuItem Header="_About"/>
</Menu> </Menu>
<TabControl <StackPanel Orientation="Vertical" DockPanel.Dock="Left" Width="150">
</StackPanel>
<TabControl DockPanel.Dock="Right"
x:Name="terminalTabControl" x:Name="terminalTabControl"
ItemsSource="{Binding TerminalViewModels}" ItemsSource="{Binding TerminalViewModels}"
SelectedItem="{Binding SelectedTerminalViewModel}"> SelectedItem="{Binding SelectedTerminalViewModel}">
<!-- Tab Template -->
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title, Mode=OneWay}" />
<Button Command="{Binding CloseRequestCommand}" Width="20" Padding="0" Margin="8 0 0 0" Content="X">
<Button.Style>
<Style TargetType="Button" x:Name="CloseButtonStyle">
<Setter Property="Visibility" Value="Visible"/>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<!-- Register additional Tab ViewModels here -->
<TabControl.Resources> <TabControl.Resources>
<DataTemplate DataType="{x:Type vm:SendReceiveViewModel}"> <DataTemplate DataType="{x:Type vm:SendReceiveViewModel}">
<v:SendReceiveView/> <v:SendReceiveView/>
</DataTemplate> </DataTemplate>
</TabControl.Resources> </TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl> </TabControl>
</DockPanel> </DockPanel>
</UserControl> </UserControl>

Loading…
Cancel
Save