es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo compartir un modelo de vista en C++ UWP?

¿Cómo puedo compartir un modelo de vista entre diferentes páginas en una aplicación C++ UWP?


Esta respuesta es una solución en C# que utiliza una propiedad estática:

public sealed partial class MainPage : Page
{
    public AppViewModel ViewModel { get; set; } = new AppViewModel();
    public static MainPage Current { get; set; }
}

public MainPage()
{
    this.InitializeComponent();
    Current = this;
}

Pero tengo problemas para traducir eso a C++.

Mi página principal de C++ actualmente se ve así:

namespace winrt::myproject::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();

        myproject::MainViewModel MainViewModel() const { return this->mainViewModel; }

    private:
        myproject::MainViewModel mainViewModel{ nullptr };
    };
}

La instancia del modelo de vista se crea en el constructor MainPage() utilizando:

this->mainViewModel = winrt::make<myproject::implementation::MainViewModel>();

Y el archivo .idl simplemente enumera la instancia del modelo de vista como una propiedad:

[default_interface]
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
    MainPage();

    MainViewModel MainViewModel{ get; };
}

¿Cómo puedo compartir el MainViewModel entre todas mis páginas?

  • ¿Qué debo cambiar en el archivo .idl y en el archivo .h?
  • ¿Necesito usar std::shared_ptr o winrt::comptr para evitar copiar la estructura y realmente compartir la misma instancia?
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para compartir un modelo de vista entre diferentes páginas en una aplicación UWP de C++, puedes usar un enfoque similar al mencionado anteriormente en la solución C#.

    En el archivo de encabezado MainPage.h, puedes declarar una propiedad static para la instancia del modelo de vista y un método static para obtenerlo:

    namespace winrt::myproject::implementation
    {
        struct MainPage : MainPageT<mainpage>
        {
            MainPage();
    
            static myproject::MainViewModel ViewModel();
    
        private:
            static myproject::MainViewModel s_mainViewModel{ nullptr }; // declarar variable estática
        };
    }
    

    En el archivo de implementación MainPage.cpp, puedes inicializar la instancia estática del modelo de vista en el constructor MainPage():

    namespace winrt::myproject::implementation
    {
        MainPage::MainPage()
        {
            InitializeComponent();
    
            if (s_mainViewModel == nullptr) // verificar si ya está inicializado
            {
                s_mainViewModel = winrt::make<myproject::implementation::mainviewmodel>();
            }
        }
    
        myproject::MainViewModel MainPage::ViewModel()
        {
            return s_mainViewModel; // devolver la instancia estática
        }
    }
    

    Luego, en tus otras páginas, puedes acceder al modelo de vista usando MainPage::ViewModel():

    namespace winrt::myproject::implementation
    {
        struct OtherPage : OtherPageT<otherpage>
        {
            OtherPage();
    
            myproject::MainViewModel ViewModel() { return MainPage::ViewModel(); } // acceder a la instancia estática a través de MainPage
        };
    }
    

    En el archivo .idl, no es necesario realizar ningún cambio ya que la instancia del modelo de vista sigue siendo una propiedad de MainPage.

    Para evitar copiar la estructura del modelo de vista y compartir realmente la misma instancia, puedes usar winrt::comptr<myproject::mainviewmodel> en lugar de un puntero sin procesar o std::shared_ptr. En ese caso, inicializarías la instancia estática de la siguiente manera:

    winrt::comptr<myproject::mainviewmodel> MainPage::s_mainViewModel{ nullptr };
    ...
    s_mainViewModel = winrt::make<myproject::implementation::mainviewmodel>();
    

    Y la devolverías así:

    cpp
    myproject::MainViewModel MainPage::ViewModel()
    {
    return s_mainViewModel.get(); // devolver el puntero sin procesar de ComPtr
    }

Comments are closed.