Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegisterViewWithRegion enhancements #210

Open
Coolkeke opened this issue Sep 9, 2024 · 4 comments
Open

RegisterViewWithRegion enhancements #210

Coolkeke opened this issue Sep 9, 2024 · 4 comments
Labels
enhancement New feature or request needs-reviewed Item needs reviewed

Comments

@Coolkeke
Copy link

Coolkeke commented Sep 9, 2024

Description

I have a practical need. In the project module development, I need to use the RegisterViewWithRegion method in Prism. However, the current method cannot let me know that my view has been successfully initialized and navigated, and I cannot pass parameters to the current page after the interface is initialized. I found that the RequestNavigate method can be passed, but there is a difference between RequestNavigate and RegisterViewWithRegion. RequestNavigate can only be used and pass parameters after the view is constructed. RegisterViewWithRegion can only initialize and navigate to the current view, and cannot pass parameters or trigger OnNavigatedTo. I don’t know if there is a method in the framework that can trigger a method similar to OnNavigatedTo after calling the RegisterViewWithRegion method to complete a basic page initialization loading method. This method is used to load data on the server.

Context

I now have a temporary solution, which is to call getContentDelegate in RegisterViewWithRegion to complete the method of getting data from the server.

public void OnInitialized(IContainerProvider containerProvider)
{
    var Region = containerProvider.Resolve<IRegionManager>(); 
    Region.RegisterViewWithRegion(SystemResource.Root, provider =>
    {
        var main = provider.Resolve<Main>();
        if (main.DataContext is MainViewModel vm) vm.Init();
        return main;
    });
}

public void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterForNavigation<Main, MainViewModel>(nameof(Main));
}

Is there any other more elegant solution? If not, can the framework support adding the actual functional requirements I proposed to expand the robustness of the current framework?

@Coolkeke Coolkeke added the enhancement New feature or request label Sep 9, 2024
@DamianSuess DamianSuess added the needs-reviewed Item needs reviewed label Sep 9, 2024
@dhhunter
Copy link

dhhunter commented Jan 7, 2025

@Coolkeke If all you really need to do is call the Init() function on your ViewModel when your View loads then you can accomplish that by using an EventTriggerBehavior on your View and a DelegateCommand on your ViewModel. IE:

<Interaction.Behaviors>
         <EventTriggerBehavior EventName="Loaded">
             <InvokeCommandAction Command="{Binding OnLoadedCommand}" />
         </EventTriggerBehavior>
</Interaction.Behaviors>

Just remember that this Event may get called more than once on the same ViewModel!

@Coolkeke
Copy link
Author

Coolkeke commented Jan 8, 2025

Loaded and RegisterViewWithRegion are substantially different and cannot be mixed

@dhhunter
Copy link

dhhunter commented Jan 8, 2025

@Coolkeke Strange, I don't seem to particularly have a problem using the XAML Loaded event on a View that was registered using RegisterViewWithRegion. I wonder what is so different about my code from yours?

Perhaps you could simply iterate on what you already have and make it an extension method, such as:

public static class RegionManagerEx
{
    public static void RegisterViewWithRegion<T>(
        this IRegionManager regionManager,
        string regionName,
        INavigationParameters navParams)
    {
        ArgumentNullException.ThrowIfNull(regionManager);

        regionManager.RegisterViewWithRegion(regionName, (provider) =>
        {
            var uri = new Uri(typeof(T).Name, UriKind.Relative);

            var navService = regionManager.Regions[regionName].NavigationService;

            var navContext = new NavigationContext(navService, uri, navParams);

            var content = provider.Resolve<T>();
            if (content is Control { DataContext: INavigationAware navigationAware })
                navigationAware.OnNavigatedTo(navContext);

            return content;
        });
    }
}

@dhhunter
Copy link

dhhunter commented Jan 8, 2025

@Coolkeke I assume that you already tried calling Init() from your ctor and that you have already tried using IActiveAware (it does not always work out of the box)? I feel like their must be a more straight forward way to accomplish your requirement. It is driving me nuts!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs-reviewed Item needs reviewed
Projects
None yet
Development

No branches or pull requests

3 participants