'Avalonia UserControl checking if it is visible before before acting on a timer
I have a loading overlay (with the View inheriting from UserControl
and the ViewModel from ViewModelBase
) that I display over the current window by putting using a <Grid>
and having the regular controls in a <StackPanel>
and then the loading screen after it in a <Border>
, binding the <Border>
's IsVisible
property to control the display of the overlay.
<Window ...>
<Grid>
<StackPanel>
<!-- Window controls here -->
</StackPanel>
<Border Background="#40000000"
IsVisible="{Binding IsLoading}">
<views:LoadingScreenView />
</Border>
</Grid>
</Window>
In the LoadingScreenViewModel
I use an HttpClient
to download a JSON file to parse and display on the loading overlay.
It is refreshed in the LoadingScreenViewModel
every 10 seconds by using a timer
private IObservable<long> timer = Observable.Interval(TimeSpan.FromSeconds(10),
Scheduler.Default);
and then subscribing to it in the ViewModel's constructor
public LoadingScreenViewModel()
{
LoadingText = "Loading...";
timer.Subscribe(async _ =>
{
var json = await _httpClient.GetStringAsync(...);
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
LoadingText = dict["result"];
});
}
The problem is that since I include the LoadingScreenView
in the window, this timer is firing every ten second, even when the loading overlay isn't displayed.
Is there any way to check if the overlay itself is visible during that Subscribe()
, passing the IsLoading property to the LoadingScreenViewModel
, or creating and destroying the View every time it is used?
Solution 1:[1]
I was able to achieve this by adding a bool isVisible
property to the LoadingScreenViewModel
, having the view inherit from ReactiveUserControl<LoadingScreenViewModel>
, and per the discussion at https://github.com/AvaloniaUI/Avalonia/discussions/7876 I achieved this in code-behind by subscribing to changes in the view's TransformedBounds property and determining if the view is visible based on if TransformedBounds is null or not.
public LoadingScreenView()
{
InitializeComponent();
this.WhenAnyValue(v => v.TransformedBounds)
.Subscribe(x => ViewModel.isVisible = x is not null);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |