Reputation: 424
I'm testing Avalonia notifications (C#, Windows 10, Visual Studio Community 2019). The following code crashes whenever I push the button and change the property 'Greeting'.
I suppose the problem is what the remarks indicate in the picture. The question is how to avoid that? How to make a notification appear after I change the content of the property Greeting? Here is the code:
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Controls.Notifications;
using System;
namespace Avalonia_test_Notifications.Views
{
public partial class MainWindow : Window
{
public ViewModels.MainWindowViewModel ViewModel;
public WindowNotificationManager Manager;
public MainWindow()
{
InitializeComponent();
this.DataContext = ViewModel;
#if DEBUG
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
Manager = new WindowNotificationManager(this);
ViewModel = new ViewModels.MainWindowViewModel(Manager);
}
private void ShowNotification(object sender, RoutedEventArgs e)
{
ViewModel.ClickEvent(sender, e);
}
}
}
and
using System;
using System.Collections.Generic;
using System.Text;
using ReactiveUI;
using System.Reactive;
namespace Avalonia_test_Notifications.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
private string _greeting = "Greetings";
public string Greeting
{
get => _greeting;
set
{
this.RaiseAndSetIfChanged(ref _greeting, value);
}
}
public Avalonia.Controls.Notifications.Notification Notification;
public Avalonia.Controls.Notifications.IManagedNotificationManager Manager;
public string [] stringArray;
public MainWindowViewModel(Avalonia.Controls.Notifications.IManagedNotificationManager manager)
{
stringArray = new string[3] { "message 1", "message 2", "message 3" };
Manager = manager;
this.WhenAnyValue(x => x.Greeting).Subscribe(x=>ShowNotification(x));
}
public void ClickEvent(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
System.Random rand = new System.Random();
int x = rand.Next(0, 3);
Greeting = stringArray[x];
}
public void ShowNotification(string s)
{
Notification = new Avalonia.Controls.Notifications.Notification("TestNotification", s, Avalonia.Controls.Notifications.NotificationType.Information, TimeSpan.FromSeconds(0));
Manager.Show(Notification);
}
}
}
and finally:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Avalonia_test_Notifications.ViewModels"
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="Avalonia_test_Notifications.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="Avalonia_test_Notifications">
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Content="Notification" Click="ShowNotification"></Button>
</StackPanel>
</Window>
Upvotes: 0
Views: 1983
Reputation: 424
It seems that the MainWindow needs some time to prepare before interacting with it. The solution I've found is to respond to changes only when IsActive is true. I'm passing a reference to the MainWindow when creating the ViewModel instead of passing a reference to the NotificationManager.
public MainWindowViewModel(Views.MainWindow Window)
{
stringArray = new string[3] { "message 1", "message 2", "message 3" };
Manager = new Avalonia.Controls.Notifications.WindowNotificationManager(Window);
this.WhenAnyValue(x => x.Greeting).WhereNotNull()
.Subscribe(x=>
{
if (Window.IsActive)
ShowNotification(x);
}
);
}
Upvotes: 0