Skip to content

Instantly share code, notes, and snippets.

@dima91
Created August 28, 2025 10:24
Show Gist options
  • Select an option

  • Save dima91/3740e632819c3f29221835da5f310334 to your computer and use it in GitHub Desktop.

Select an option

Save dima91/3740e632819c3f29221835da5f310334 to your computer and use it in GitHub Desktop.
Observer pattern among two ViewModels using Avalonia and ReactiveUI frameworks
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaObserver.ViewModels"
xmlns:views="using:AvaloniaObserver.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaObserver.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaObserver">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" >
<ContentControl Content="{Binding PublisherControl}"/>
<ContentControl VerticalAlignment="Top" Content="{Binding SubscriberControl}"/>
</StackPanel>
</Window>
using ReactiveUI;
using System;
using System.Windows.Input;
using System.Reactive;
using System.Reactive.Linq;
namespace AvaloniaObserver.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
public PublisherControlViewModel PublisherControl { get; }
public SubscriberControlViewModel SubscriberControl { get; }
public MainWindowViewModel()
{
PublisherControl = new PublisherControlViewModel();
SubscriberControl = new SubscriberControlViewModel(PublisherControl.SubmitTextCommand);
}
}
<UserControl 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="using:AvaloniaObserver.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:PublisherControlViewModel"
x:Class="AvaloniaObserver.Views.PublisherControlView">
<Design.DataContext>
<vm:PublisherControlViewModel/>
</Design.DataContext>
<StackPanel Spacing="10" Margin="20" VerticalAlignment="Center">
<TextBox Watermark="Insert text here..."
Text="{Binding InputText}"
Name="InputText"
Height="200"
Width="400"
AcceptsReturn="True"
TextWrapping="Wrap" />
<Button Content="Conferma" HorizontalAlignment="Center" Command="{Binding SubmitTextCommand}" />
</StackPanel>
</UserControl>
using System;
using System.Reactive.Linq;
using System.Reactive;
using ReactiveUI;
namespace AvaloniaObserver.ViewModels;
public partial class PublisherControlViewModel : ViewModelBase
{
// InputTextConent property will contain the wrote message
private string _InputTextValue;
public string InputText
{
get => _InputTextValue;
set => this.RaiseAndSetIfChanged(ref _InputTextValue, value);
}
// With the SubmitTextCommand the observer will be notified regarding the text submission
public ReactiveCommand<Unit, string> SubmitTextCommand { get; }
public PublisherControlViewModel()
{
_InputTextValue = string.Empty;
SubmitTextCommand = ReactiveCommand.Create(SubmitText, this.WhenAnyValue(x => x.InputText, data => !string.IsNullOrEmpty(data)));
}
public string SubmitText()
{
return InputText;
}
}
<UserControl 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="using:AvaloniaObserver.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:SubscriberControlViewModel"
x:Class="AvaloniaObserver.Views.SubscriberControlView">
<StackPanel Spacing="10" Margin="20" VerticalAlignment="Center">
<TextBox Watermark="Text will be displayed here..."
Text="{Binding ReversedText}"
Name="ReversedText"
Height="200"
Width="400"
AcceptsReturn="True"
TextWrapping="Wrap"
IsReadOnly="True" />
</StackPanel>
</UserControl>
using System;
using System.Windows.Input;
using System.Reactive.Linq;
using System.Reactive;
using ReactiveUI;
namespace AvaloniaObserver.ViewModels;
public partial class SubscriberControlViewModel : ViewModelBase
{
private string _ReversedTextValue;
public string ReversedText
{
get => _ReversedTextValue;
set => this.RaiseAndSetIfChanged(ref _ReversedTextValue, value);
}
public SubscriberControlViewModel(ReactiveCommand<Unit, string> extCommand)
{
_ReversedTextValue = string.Empty;
extCommand
.Subscribe(data =>
{
UpdateText(data);
});
}
public void UpdateText(string data)
{
char[] dataArray = data.ToCharArray();
Array.Reverse(dataArray);
ReversedText = new string(dataArray);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment