-
I would like to create a I would like to know if somebody knows if there is already something like this or if there are some ideas how such a control would look like concept-wise. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Panel.ZIndex can be used on each Panel / Canvas / Grid afaik. |
Beta Was this translation helpful? Give feedback.
-
There are many options, but I think I would just use an |
Beta Was this translation helpful? Give feedback.
-
Thank you for the feedback! I came up with this solution:
<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:StackedPages.ViewModels"
x:Class="StackedPages.Views.StackView"
x:DataType="vm:StackViewModel">
<Grid
ColumnDefinitions="1*"
RowDefinitions="1* ,Auto">
<Panel
Grid.Column="0"
Grid.Row="0"
Name="VisibleViewPanel">
</Panel>
<Button
Grid.Column="0"
Grid.Row="1"
Content="X"
IsEnabled="{Binding CanClose}"
Command="{Binding CloseCommand}"
ToolTip.Tip="Close"/>
</Grid>
</UserControl>
using Avalonia.Controls;
using ReactiveUI;
using StackedPages.ViewModels;
using System;
namespace StackedPages.Views;
public partial class StackView : UserControl
{
private IDisposable _VisibleViewSubscription;
public StackView()
{
InitializeComponent();
}
protected override void OnDataContextBeginUpdate()
{
_VisibleViewSubscription?.Dispose();
_VisibleViewSubscription = null;
base.OnDataContextBeginUpdate();
}
protected override void OnDataContextEndUpdate()
{
if (DataContext == null || DataContext is not StackViewModel stackViewModel)
{
return;
}
_VisibleViewSubscription = stackViewModel
.WhenAnyValue(x => x.VisibleView)
.Subscribe(HandleVisibleViewChanged);
base.OnDataContextEndUpdate();
}
private void HandleVisibleViewChanged(Control visibleView)
{
VisibleViewPanel.Children.Clear();
if (visibleView == null)
{
return;
}
VisibleViewPanel.Children.Add(visibleView);
}
}
using Avalonia.Controls;
using DynamicData.Binding;
using ReactiveUI;
using System;
using System.Windows.Input;
namespace StackedPages.ViewModels;
internal interface IStackViewModelItem : IDisposable
{
StackViewModel StackViewModel { get; init; }
Control GetView();
}
internal class StackViewModel : ReactiveObject
{
internal ObservableCollectionExtended<IStackViewModelItem> Items { get; private init; } = [];
private Control _VisibleView = null;
internal Control VisibleView
{
get => _VisibleView;
set => this.RaiseAndSetIfChanged(ref _VisibleView, value);
}
internal ICommand AddCommand => ReactiveCommand.Create<IStackViewModelItem>(Add);
internal void Add(IStackViewModelItem item)
{
if (item == null)
{
return;
}
Control view = item.GetView();
if (view == null)
{
return;
}
VisibleView = view;
Items.Add(item);
CanClose = true;
}
private bool _CanClose = false;
internal bool CanClose
{
get => _CanClose;
set => this.RaiseAndSetIfChanged(ref _CanClose, value);
}
internal ICommand CloseCommand => ReactiveCommand.Create(Close);
private void Close()
{
if (Items.Count == 0)
{
return;
}
IStackViewModelItem item = Items[^1];
Items.RemoveAt(Items.Count - 1);
item?.Dispose();
if (Items.Count == 0)
{
VisibleView = null;
return;
}
item = Items[^1];
Control view = item?.GetView();
VisibleView = view;
CanClose = Items.Count > 0;
}
} Example project: StackedPages.2024-04-17.14-05-55.mp4 |
Beta Was this translation helpful? Give feedback.
Thank you for the feedback!
I came up with this solution:
StackView.axaml
: