diff --git a/PettingZoo/Program.cs b/PettingZoo/Program.cs index 2940ce7..aefc18a 100644 --- a/PettingZoo/Program.cs +++ b/PettingZoo/Program.cs @@ -42,7 +42,6 @@ namespace PettingZoo container.Register(); container.Register(); container.Register(); - container.Register(); container.Register(); diff --git a/PettingZoo/UI/BindingProxy.cs b/PettingZoo/UI/BindingProxy.cs new file mode 100644 index 0000000..4bc6e38 --- /dev/null +++ b/PettingZoo/UI/BindingProxy.cs @@ -0,0 +1,24 @@ +using System.Windows; + +namespace PettingZoo.UI +{ + public class BindingProxy : Freezable + { + protected override Freezable CreateInstanceCore() + { + return new BindingProxy(); + } + + + public object Data + { + get => GetValue(DataProperty); + set => SetValue(DataProperty, value); + } + + + // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... + public static readonly DependencyProperty DataProperty = + DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); + } +} diff --git a/PettingZoo/UI/Main/MainWindow.xaml.cs b/PettingZoo/UI/Main/MainWindow.xaml.cs index c41d85e..99e2330 100644 --- a/PettingZoo/UI/Main/MainWindow.xaml.cs +++ b/PettingZoo/UI/Main/MainWindow.xaml.cs @@ -16,12 +16,12 @@ namespace PettingZoo.UI.Main private readonly MainWindowViewModel viewModel; - public MainWindow(IConnectionFactory connectionFactory, IConnectionDialog connectionDialog, ISubscribeDialog subscribeDialog, ITabFactory tabFactory) + public MainWindow(IConnectionFactory connectionFactory, IConnectionDialog connectionDialog, ISubscribeDialog subscribeDialog) { WindowStartupLocation = WindowStartupLocation.CenterScreen; InitializeComponent(); - viewModel = new MainWindowViewModel(connectionFactory, connectionDialog, subscribeDialog, tabFactory); + viewModel = new MainWindowViewModel(connectionFactory, connectionDialog, subscribeDialog); DataContext = viewModel; Dispatcher.ShutdownStarted += OnDispatcherShutDownStarted; diff --git a/PettingZoo/UI/Main/MainWindowViewModel.cs b/PettingZoo/UI/Main/MainWindowViewModel.cs index ad71060..2d8d033 100644 --- a/PettingZoo/UI/Main/MainWindowViewModel.cs +++ b/PettingZoo/UI/Main/MainWindowViewModel.cs @@ -12,7 +12,7 @@ using PettingZoo.UI.Tab; namespace PettingZoo.UI.Main { - public class MainWindowViewModel : BaseViewModel, IAsyncDisposable + public class MainWindowViewModel : BaseViewModel, IAsyncDisposable, ITabHost { private readonly IConnectionFactory connectionFactory; private readonly IConnectionDialog connectionDialog; @@ -66,12 +66,11 @@ namespace PettingZoo.UI.Main public MainWindowViewModel(IConnectionFactory connectionFactory, IConnectionDialog connectionDialog, - ISubscribeDialog subscribeDialog, ITabFactory tabFactory) + ISubscribeDialog subscribeDialog) { this.connectionFactory = connectionFactory; this.connectionDialog = connectionDialog; this.subscribeDialog = subscribeDialog; - this.tabFactory = tabFactory; connectionStatus = GetConnectionStatus(null); @@ -81,6 +80,8 @@ namespace PettingZoo.UI.Main publishCommand = new DelegateCommand(PublishExecute, IsConnectedCanExecute); subscribeCommand = new DelegateCommand(SubscribeExecute, IsConnectedCanExecute); closeTabCommand = new DelegateCommand(CloseTabExecute, CloseTabCanExecute); + + tabFactory = new ViewTabFactory(this, closeTabCommand); } @@ -113,7 +114,7 @@ namespace PettingZoo.UI.Main if (connectionDialogParams.Subscribe) { var subscriber = connection.Subscribe(connectionDialogParams.Exchange, connectionDialogParams.RoutingKey); - AddTab(tabFactory.CreateSubscriberTab(CloseTabCommand, subscriber)); + AddTab(tabFactory.CreateSubscriberTab(connection, subscriber)); } @@ -150,7 +151,7 @@ namespace PettingZoo.UI.Main subscribeDialogParams = newParams; var subscriber = connection.Subscribe(subscribeDialogParams.Exchange, subscribeDialogParams.RoutingKey); - AddTab(tabFactory.CreateSubscriberTab(CloseTabCommand, subscriber)); + AddTab(tabFactory.CreateSubscriberTab(connection, subscriber)); } @@ -159,7 +160,7 @@ namespace PettingZoo.UI.Main if (connection == null) return; - AddTab(tabFactory.CreatePublisherTab(CloseTabCommand, connection)); + AddTab(tabFactory.CreatePublisherTab(connection)); } @@ -194,7 +195,7 @@ namespace PettingZoo.UI.Main } - private void AddTab(ITab tab) + public void AddTab(ITab tab) { Tabs.Add(tab); ActiveTab = tab; @@ -233,7 +234,7 @@ namespace PettingZoo.UI.Main public class DesignTimeMainWindowViewModel : MainWindowViewModel { - public DesignTimeMainWindowViewModel() : base(null!, null!, null!, null!) + public DesignTimeMainWindowViewModel() : base(null!, null!, null!) { } } diff --git a/PettingZoo/UI/Tab/ITabFactory.cs b/PettingZoo/UI/Tab/ITabFactory.cs index ca290a7..e7f5ac3 100644 --- a/PettingZoo/UI/Tab/ITabFactory.cs +++ b/PettingZoo/UI/Tab/ITabFactory.cs @@ -1,5 +1,4 @@ -using System.Windows.Input; -using PettingZoo.Core.Connection; +using PettingZoo.Core.Connection; namespace PettingZoo.UI.Tab { @@ -9,7 +8,7 @@ namespace PettingZoo.UI.Tab public interface ITabFactory { - ITab CreateSubscriberTab(ICommand closeTabCommand, ISubscriber subscriber); - ITab CreatePublisherTab(ICommand closeTabCommand, IConnection connection); + ITab CreateSubscriberTab(IConnection connection, ISubscriber subscriber); + ITab CreatePublisherTab(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null); } } diff --git a/PettingZoo/UI/Tab/ITabHost.cs b/PettingZoo/UI/Tab/ITabHost.cs new file mode 100644 index 0000000..ec570df --- /dev/null +++ b/PettingZoo/UI/Tab/ITabHost.cs @@ -0,0 +1,7 @@ +namespace PettingZoo.UI.Tab +{ + public interface ITabHost + { + void AddTab(ITab tab); + } +} diff --git a/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs b/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs index 6874615..dfab447 100644 --- a/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs +++ b/PettingZoo/UI/Tab/Publisher/PublisherViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text; using System.Windows.Controls; using System.Windows.Input; using PettingZoo.Core.Connection; @@ -73,7 +74,7 @@ namespace PettingZoo.UI.Tab.Publisher public IEnumerable ToolbarCommands => toolbarCommands; - public PublisherViewModel(IConnection connection) + public PublisherViewModel(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null) { this.connection = connection; @@ -84,7 +85,10 @@ namespace PettingZoo.UI.Tab.Publisher new TabToolbarCommand(PublishCommand, PublisherViewStrings.CommandPublish, SvgIconHelper.LoadFromResource("/Images/PublishSend.svg")) }; - SetMessageTypeControl(MessageType.Raw); + if (fromReceivedMessage != null) + SetMessageTypeControl(fromReceivedMessage); + else + SetMessageTypeControl(MessageType.Raw); } @@ -126,6 +130,82 @@ namespace PettingZoo.UI.Tab.Publisher publishCommand.RaiseCanExecuteChanged(); } + + + private void SetMessageTypeControl(ReceivedMessageInfo fromReceivedMessage) + { + // TODO move to individual viewmodels? + if (IsTapetiMessage(fromReceivedMessage, out var assemblyName, out var className)) + { + var tapetiPublisherViewModel = new TapetiPublisherViewModel(connection) + { + Exchange = fromReceivedMessage.Exchange, + RoutingKey = fromReceivedMessage.RoutingKey, + + AssemblyName = assemblyName, + ClassName = className, + CorrelationId = fromReceivedMessage.Properties.CorrelationId ?? "", + ReplyTo = fromReceivedMessage.Properties.ReplyTo ?? "", + Payload = Encoding.UTF8.GetString(fromReceivedMessage.Body) + }; + + tapetiPublisherView ??= new TapetiPublisherView(tapetiPublisherViewModel); + SetMessageTypeControl(MessageType.Tapeti); + } + else + { + var rawPublisherViewModel = new RawPublisherViewModel(connection) + { + Exchange = fromReceivedMessage.Exchange, + RoutingKey = fromReceivedMessage.RoutingKey, + + CorrelationId = fromReceivedMessage.Properties.CorrelationId ?? "", + ReplyTo = fromReceivedMessage.Properties.ReplyTo ?? "", + Priority = fromReceivedMessage.Properties.Priority?.ToString() ?? "", + AppId = fromReceivedMessage.Properties.AppId ?? "", + ContentEncoding = fromReceivedMessage.Properties.ContentEncoding ?? "", + ContentType = fromReceivedMessage.Properties.ContentType ?? "", + Expiration = fromReceivedMessage.Properties.Expiration ?? "", + MessageId = fromReceivedMessage.Properties.MessageId ?? "", + Timestamp = fromReceivedMessage.Properties.Timestamp?.ToString() ?? "", + TypeProperty = fromReceivedMessage.Properties.Type ?? "", + UserId = fromReceivedMessage.Properties.UserId ?? "", + + Payload = Encoding.UTF8.GetString(fromReceivedMessage.Body) + }; + + foreach (var header in fromReceivedMessage.Properties.Headers) + rawPublisherViewModel.Headers.Add(new RawPublisherViewModel.Header + { + Key = header.Key, + Value = header.Value + }); + + rawPublisherView = new RawPublisherView(rawPublisherViewModel); + SetMessageTypeControl(MessageType.Raw); + } + } + + + private static bool IsTapetiMessage(ReceivedMessageInfo receivedMessage, out string assemblyName, out string className) + { + assemblyName = ""; + className = ""; + + if (receivedMessage.Properties.ContentType != @"application/json") + return false; + + if (!receivedMessage.Properties.Headers.TryGetValue(@"classType", out var classType)) + return false; + + var parts = classType.Split(':'); + if (parts.Length != 2) + return false; + + className = parts[0]; + assemblyName = parts[1]; + return true; + } } diff --git a/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml b/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml index 7da2b71..deef3cc 100644 --- a/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml +++ b/PettingZoo/UI/Tab/Subscriber/SubscriberView.xaml @@ -18,9 +18,13 @@ + + + @@ -30,6 +34,13 @@ + + + + + + + @@ -58,8 +69,10 @@