{"id":57995,"date":"2023-01-29T09:01:35","date_gmt":"2023-01-29T08:01:35","guid":{"rendered":"https:\/\/ar3dp.de\/docs\/programmieren\/net-maui-basis-applikation-app-template\/2-viewmodels\/"},"modified":"2023-01-29T09:01:35","modified_gmt":"2023-01-29T08:01:35","slug":"viewmodels","status":"publish","type":"docs","link":"https:\/\/ar3dp.de\/en\/docs\/programmieren\/net-maui-basis-applikation-app-template\/viewmodels\/","title":{"rendered":"ViewModels"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Die <code>ViewModels<\/code> beinhalten die Funktionen und Eigenschaften der einzelnen <code>Views<\/code>. Bei der Namensnennung ist der Name des <code>ViewModels<\/code> identisch zur <code>View<\/code>, so bleibt das Projekt \u00fcbersichtlicher.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csharp&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;C#&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;csharp&quot;}\">public DashboardPageViewModel() { ... }\npublic DashboardPage() { ... }<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Des Weiteren sind alle <code>ViewModels<\/code> und <code>Views<\/code> in logische Unterordner organisiert.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ViewModels<\/strong>: Alle <code>ViewModels<\/code> der Hauptansichten, welche im <code>AppShell<\/code> angew\u00e4hlt werden k\u00f6nnen<\/li>\n\n\n\n<li>ViewModels\\<strong>Modals<\/strong>: Alle <code>ViewModels<\/code> f\u00fcr modale Seiten, zu welchen navigiert werden kann <\/li>\n\n\n\n<li>ViewModels\\<strong>Pages<\/strong>: Alle <code>ViewModels<\/code> weitere statische Seiten<\/li>\n\n\n\n<li>ViewModels\\<strong>Settings<\/strong>: Alle <code>ViewModels<\/code> f\u00fcr die einzelnen Einstellungesseiten, welche \u00fcber die <code>SettingsPage<\/code> aufgerufen werden k\u00f6nnen<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Alle <code>ViewModels<\/code> nutzen <code>DependencyInjection<\/code>, hier wird beim Erstellen der aktuelle <code>IDispatcher<\/code> und <code>IServiceProvider<\/code> injiziert, welche sp\u00e4ter f\u00fcr weitere Funktionen verwendet werden k\u00f6nnen.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csharp&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;C#&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;csharp&quot;}\">#region Ctor\npublic DashboardPageViewModel(IDispatcher dispatcher, IServiceProvider provider) : base(dispatcher, provider)\n{\n    Dispatcher = dispatcher;\n    OnDataChanged = Refresh;\n}\n#endregion<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Base- &amp; AppViewModel<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Unser Template bietet zwei Basisklassen. von welchen alle weiteren <code>ViewModels<\/code> erben sollten.\u2002Dabei unterscheiden sich beide Klassen wie folgt.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">BaseViewModel<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Das <code>BaseViewModel<\/code> bietet alle grundlegenden und notwendigen Eigenschaften und Funktionen, welche ein <code>ViewModel<\/code> ben\u00f6tigt, um richtig zu funktionieren. Einfache Seiten, wie die Einstellungsseiten, k\u00f6nnen von dieser Klasse erben, da kein Zugriff auf die App-Inhalte n\u00f6tig ist.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">AppViewModel<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Das <code>AppViewModel<\/code> hingegen, welches ebenfalls vom <code>BaseViewModel<\/code> erbt, beinhaltet zus\u00e4tzlich noch allen appspezifischen Eigenschaften und Funktionen. Das k\u00f6nnten zum Beispiel, bei einer Aktien-App, die Depots sein. Somit sollten alle weiteren <code>ViewModels<\/code>, welche Inhalte der App anzeigen und verarbeiten, auch vom <code>AppViewModel<\/code> erben.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Beispiel<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Als Beispiel, das <code>AppViewModel<\/code> unserer &#8220;Aktien-Monitor-App&#8221;. Die einzelnen Funktionen wurden gek\u00fcrzt, um die Datei \u00fcbersichtlicher zu halten.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csharp&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;C#&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;csharp&quot;}\">namespace AppBasement.ViewModels\n{\n    [QueryProperty(nameof(PrimaryDepot), &quot;primarydepot&quot;)]\n    [QueryProperty(nameof(PrimaryWatchlist), &quot;primarywatchlist&quot;)]\n    [QueryProperty(nameof(SelectedDepot), &quot;depot&quot;)]\n    [QueryProperty(nameof(CurrentStock), &quot;stock&quot;)]\n    [QueryProperty(nameof(SelectedWatchlist), &quot;watchlist&quot;)]\n    [QueryProperty(nameof(SelectedMarketplace), &quot;marketplace&quot;)]\n    public partial class AppViewModel : BaseViewModel\n    {\n\n        #region QueryParameter\n        [ObservableProperty]\n        protected Depot primaryDepot;\n        partial void OnPrimaryDepotChanged(Depot value)\n        {\n            \/\/ Binding this directly seems to cause issues with the SfCircularGauge content...\n            TotalWorth = value?.TotalWorth ?? 0;\n            TotalCosts = value?.TotalCosts ?? 0;\n            Growth = value?.Growth ?? 0;\n            if (value != null)\n            {\n                value.DepotChanged -= _primaryDepot_DepotChanged;\n                value.DepotChanged += _primaryDepot_DepotChanged;\n            }\n        }\n\n        [ObservableProperty]\n        protected Depot selectedDepot;\n\n        [ObservableProperty]\n        protected WatchList primaryWatchlist;\n\n        [ObservableProperty]\n        protected WatchList selectedWatchlist;\n\n        [ObservableProperty]\n        protected Marketplace selectedMarketplace;\n\n        [ObservableProperty]\n        Stock currentStock;\n        #endregion\n\n        #region Properties\n\n        #region Actions\n        public Func&lt;Task&gt; OnDataChanged;\n        #endregion\n\n        #region States\n\n        [ObservableProperty]\n        bool hasDepot = false;\n\n        [ObservableProperty]\n        bool hasWatchlist = false;\n\n        [ObservableProperty]\n        bool isLoadingDepots = false;\n\n        [ObservableProperty]\n        bool isLoadingWatchlists = false;\n\n        [ObservableProperty]\n        double totalWorth = 0;\n\n        [ObservableProperty]\n        double totalCosts = 0;\n\n        [ObservableProperty]\n        double growth = 0;\n\n        #endregion\n\n        #region Forms\n\n        [ObservableProperty]\n        bool keepFormOpen = false;\n\n        #endregion\n\n        #region ModalPopups\n\n        [ObservableProperty]\n        bool tutorialShown = false;\n\n        [ObservableProperty]\n        bool changeInfosShown = false;\n\n        #endregion\n\n        #endregion\n\n        #region Collections\n        [ObservableProperty]\n        [NotifyPropertyChangedFor(nameof(HasDepot))]\n        ObservableCollection&lt;Depot&gt; depots = new();\n        partial void OnDepotsChanged(ObservableCollection&lt;Depot&gt; value)\n        {\n            HasDepot = value?.Count &gt; 0;\n        }\n\n        [ObservableProperty]\n        [NotifyPropertyChangedFor(nameof(HasWatchlist))]\n        ObservableCollection&lt;WatchList&gt; watchlists = new();\n        partial void OnWatchlistsChanged(ObservableCollection&lt;WatchList&gt; value)\n        {\n            HasWatchlist = value?.Count &gt; 0;\n        }\n\n        [ObservableProperty]\n        ObservableCollection&lt;Marketplace&gt; marketplaces = new();\n\n        #endregion\n\n        #region Constructor\n        public AppViewModel(IDispatcher dispatcher) : base(dispatcher)\n        {\n            Dispatcher = dispatcher;\n            LoadSettings();\n        }\n        #endregion\n\n        #region Events\n        public void Pages_Loaded(object sender, EventArgs e)\n        {\n            Task.Run(OnLoadedAsync);\n        }\n\n        protected void _primaryDepot_DepotChanged(object sender, DepotChangedEventArgs e)\n        {\n            try\n            {\n                if (sender is Depot primary)\n                {\n                    TotalWorth = primary.TotalWorth;\n                    TotalCosts = primary.TotalCosts;\n                    Growth = primary.Growth;\n                }\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log Error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        public void Depots_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)\n        {\n            OnPropertyChanged(nameof(Depots));\n#if CloudSync\n            if (SettingsApp.Cloud_EnableSync)\n            {\n                SettingsApp.SyncToCloud(CloudSettingsIdentifier.Customers);\n            }\n#endif\n        }\n        public void Stocks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)\n        {\n            OnPropertyChanged(nameof(Depots));\n#if CloudSync\n            if (SettingsApp.Cloud_EnableSync)\n            {\n                SettingsApp.SyncToCloud(CloudSettingsIdentifier.Customers);\n            }\n#endif\n        }\n\n        protected void CurrentDepot_DepotChanged(object sender, DepotChangedEventArgs e)\n        {\n            OnPropertyChanged(nameof(Depots));\n#if CloudSync\n            if (SettingsApp.Cloud_EnableSync)\n            {\n                SettingsApp.SyncToCloud(CloudSettingsIdentifier.Customers);\n            }\n#endif\n        }\n        #endregion\n\n        #region Commands\n\n        #region Database\n        [RelayCommand]\n        protected async Task LoadDepotsFromDatabase()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task LoadWatchlistsFromDatabase()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n        #endregion\n\n        #region ShellNavigation\n        [RelayCommand]\n        protected async Task NewItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task EditItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task ViewItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task DeleteItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task ExportItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task AddTransactionToItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task AddDividendToItem(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task AddStocksToDepot(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        [RelayCommand]\n        protected async Task ShowStockDetails(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task RefreshStockRate(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task ShowDepotDetails(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        [RelayCommand]\n        protected async Task MakeDepotPrimary(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n        #endregion\n\n        #region ListView\n        [RelayCommand]\n        protected async Task ActionFromHold(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        [RelayCommand]\n        protected async Task ActionFromTap(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        [RelayCommand]\n        protected async Task ActionFromDoubleTap(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        [RelayCommand]\n        protected void ActionWhileSwiping(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        [RelayCommand]\n        protected async Task ActionFromSwipeGesture(object parameter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n            IsBusy = false;\n        }\n\n        #endregion\n\n        #region Wiki\n        [RelayCommand]\n        protected async Task OpenWikiUri(object paramter)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log Error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region Methods\n\n        #region DataLoading\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ Loads the data needed for this input form modal.\n        \/\/\/ Attention! This code runs not on the UI Thread!\n        \/\/\/ &lt;\/summary&gt;\n        \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\n        protected async Task OnLoadDataAsync()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n        protected async Task OnLoadWatchlistsAsync()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ Updates the needed information from the static AppData.\n        \/\/\/ Important: This must run on the UIThread!\n        \/\/\/ &lt;\/summary&gt;\n        protected void UpdateFromStaticAppData()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ Updates the needed information from the static AppData.\n        \/\/\/ Important: This must run on the UIThread!\n        \/\/\/ &lt;\/summary&gt;\n        protected void UpdateWatchlistFromStaticAppData()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        protected async Task UpdateStockRateAsync(Stock stock, int daysBack = 7)\n        {\n            await UpdateStockRatesAsync(new() { stock }, daysBack);\n        }\n        protected async Task UpdateStockRatesAsync(List&lt;Stock&gt; stocks, int daysBack = 7)\n        {\n            try\n            {\n                \/\/ Something to be done here...\n            }\n            catch (Exception exc)\n            {\n                \/\/Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region Lifecycle\n        public async Task OnLoadedAsync()\n        {\n            try\n            {\n                \/\/ Something to be done here...\n                EventManager.Instance.LogInfo(new()\n                {\n                    Message = $&quot;{AppInfo.Current.Name}: {nameof(OnLoadedAsync)} called from {nameof(AppViewModel)}.&quot;,\n                    SourceName = nameof(OnLoadedAsync),\n                });\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n\n        public async Task OnAppearing()\n        {\n            try\n            {\n                await Task.Delay(1);\n                EventManager.Instance.LogInfo(new()\n                {\n                    Message = $&quot;{AppInfo.Current.Name}: {nameof(OnAppearing)} called from {nameof(AppViewModel)}.&quot;,\n                    SourceName = nameof(OnAppearing),\n                });\n            }\n            catch (Exception exc)\n            {\n                \/\/ Log error\n                EventManager.Instance.LogError(exc);\n            }\n        }\n        #endregion\n    }\n}<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Die ViewModels beinhalten die Funktionen und Eigenschaften der einzelnen Views. Bei der Namensnennung ist der Name des ViewModels identisch zur View, so bleibt das Projekt \u00fcbersichtlicher. Des Weiteren sind alle ViewModels und Views in logische Unterordner organisiert. Alle ViewModels nutzen DependencyInjection, hier wird beim Erstellen der aktuelle IDispatcher und IServiceProvider injiziert, welche sp\u00e4ter f\u00fcr weitere&#8230;<\/p>","protected":false},"author":1,"featured_media":0,"parent":57992,"menu_order":5,"comment_status":"open","ping_status":"closed","template":"","meta":{"_featured":false,"_is_vendor_doc":"0","footnotes":""},"doc_tag":[],"class_list":["post-57995","docs","type-docs","status-publish","hentry"],"comment_count":0,"_links":{"self":[{"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs\/57995","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/comments?post=57995"}],"version-history":[{"count":1,"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs\/57995\/revisions"}],"predecessor-version":[{"id":58735,"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs\/57995\/revisions\/58735"}],"up":[{"embeddable":true,"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs\/57992"}],"next":[{"title":"Views","link":"https:\/\/ar3dp.de\/en\/docs\/programmieren\/net-maui-basis-applikation-app-template\/views\/","href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs\/57996"}],"prev":[{"title":"Localization","link":"https:\/\/ar3dp.de\/en\/docs\/programmieren\/net-maui-basis-applikation-app-template\/lokalisierung\/","href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/docs\/58003"}],"wp:attachment":[{"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/media?parent=57995"}],"wp:term":[{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/ar3dp.de\/en\/wp-json\/wp\/v2\/doc_tag?post=57995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}