3

New to AvaloniaUI / ReactiveUI, but not to WPF. I'm trying to play around with AvaloniaUI to see if I want to port my entire WPF project over to it, but I've ran into a little bit of a hurdle. I've found many examples of binding commands to 'self', eg. UserControl binding in UserControlModel, MainWindow binding in MainWindowModel, but nothing on a child UserControl binding to Parent model command. I've based my MainWindowModel.cs after one of the basic examples given by AvaloniaUI as shown. I basically want a button on a page to select which page in the Pages[] list to go to. But for now just go to the next one in the list. In WPF I would just the NavigationService and URI to nav, but wanted to try out this paradigm in Avalonia UI.

MainWindowModel.cs

public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            // Set current page to first on start up
            _CurrentPage = Pages[0];

            // Create Observables which will activate to deactivate our commands based on CurrentPage state
            var canNavNext = this.WhenAnyValue(x => x.CurrentPage.CanNavigateNext);
            var canNavPrev = this.WhenAnyValue(x => x.CurrentPage.CanNavigatePrevious);

            NavigateNextCommand = ReactiveCommand.Create(NavigateNext, canNavNext);
            NavigatePreviousCommand = ReactiveCommand.Create(NavigatePrevious, canNavPrev);
        }

        // A read.only array of possible pages
        private readonly PageViewModelBase[] Pages = 
        { 
            new FirstPageViewModel(),
            new SecondPageViewModel(),
            new ThirdPageViewModel()
        };

        // The default is the first page
        private PageViewModelBase _CurrentPage;

        /// <summary>
        /// Gets the current page. The property is read-only
        /// </summary>
        public PageViewModelBase CurrentPage
        {
            get { return _CurrentPage; }
            private set { this.RaiseAndSetIfChanged(ref _CurrentPage, value); }
        }

        /// <summary>
        /// Gets a command that navigates to the next page
        /// </summary>
        public ICommand NavigateNextCommand { get; }

        private void NavigateNext()
        {
            // get the current index and add 1
            var index = Pages.IndexOf(CurrentPage) + 1;

            //  /!\ Be aware that we have no check if the index is valid. You may want to add it on your own. /!\
            CurrentPage = Pages[index];
        }

        /// <summary>
        /// Gets a command that navigates to the previous page
        /// </summary>
        public ICommand NavigatePreviousCommand { get; }

        private void NavigatePrevious()
        {
            // get the current index and subtract 1
            var index = Pages.IndexOf(CurrentPage) - 1;

            //  /!\ Be aware that we have no check if the index is valid. You may want to add it on your own. /!\
            CurrentPage = Pages[index];
        }
    }  

The example binds the navigation buttons in MainWindow.axaml

 <TransitioningContentControl Content="{Binding CurrentPage}" />

 <StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="5"
        HorizontalAlignment="Right">
     <Button Command="{Binding NavigatePreviousCommand}" Content="Back" />
     <Button Command="{Binding NavigateNextCommand}" Content="Next" />
</StackPanel>

I would like to bind to these commands in childView Page buttons. Is there a way to do that? Or do I need to link up an Event handler to signal to the Parent (MainWindow) to do it? And if so what does a basic example look like?

Thanks!

I've tried a number of route examples but none are related to the Parent-Child relationship.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.