{"id":304704,"date":"2020-06-02T15:00:23","date_gmt":"2020-06-02T15:00:23","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=304704"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=304704","title":{"rendered":"Avalonia Tutorial: \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f MVVM \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/505036\/\">\n<h2 id=\"avalonia-eto\">Avalonia \u044d\u0442\u043e?<\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/avaloniaui.net\/docs\">Avalonia<\/a> \u2013 \u044d\u0442\u043e \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 XAML \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b .Net. \u0414\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043d\u0430 WPF\/UWP\/Xamarin \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0435\u043d \u0438 \u043f\u0440\u043e\u0441\u0442 \u0432 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0438. Avalonia \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 Windows, Linux, macOS, \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u0430 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Android \u0438 iOS. \u0420\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f open-source. <\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u0441\u044b\u043b\u043a\u0430\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/349394\/\">\u0420\u0435\u043b\u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0431\u0435\u0442\u044b \u043a\u0440\u043e\u0441\u0441-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e XAML UI-\u0442\u0443\u043b\u043a\u0438\u0442\u0430 Avalonia;<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/481102\/\">\u0420\u0435\u043b\u0438\u0437 \u043a\u0440\u043e\u0441\u0441-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e .NET UI-\u0442\u0443\u043b\u043a\u0438\u0442\u0430 AvaloniaUI 0.9;<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=8qzqweimcFs\">\u041d\u0438\u043a\u0438\u0442\u0430 \u0426\u0443\u043a\u0430\u043d\u043e\u0432 \u2014 AvaloniaUI \u2014 \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 XAML UI-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 .NET Core.<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"motivaciya-dlya-stati\">\u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438<\/h2>\n<p>  <\/p>\n<p>\u0410\u0432\u0442\u043e\u0440\u0443 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e WPF\/UWP \u0438 \u0435\u0441\u0442\u044c \u043e\u043f\u044b\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445. \u0423 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u043c\u0438\u043d\u0443\u0441\u044b, \u043d\u043e \u0441\u0430\u043c\u044b\u043c \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u043c \u0431\u044b\u043b\u043e \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c\u0438. \u0414\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Microsoft \u043d\u0430 Windows \u0441\u0440\u0435\u0434\u0435, \u0434\u0430\u0436\u0435 \u0441 \u043d\u0430\u043b\u0438\u0447\u0438\u0435\u043c Mono \u0438 \u0432\u044b\u0445\u043e\u0434\u043e\u043c Net Core, \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0432\u043d\u0435 \u043c\u0438\u0440\u0430 .net \u2013 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u043e \u0441\u0442\u0435\u0440\u0435\u043e\u0442\u0438\u043f, \u0447\u0442\u043e C# \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f Windows. \u0418 \u0435\u0441\u043b\u0438 \u0434\u043b\u044f back-end \u2013 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 .Net Core, \u0441\u0442\u0430\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c, \u0442\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u0441\u043a\u0442\u043e\u043f\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e. \u041f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 WinForms \u0438 WPF \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441 \u043f\u043e\u0434 .Net Core, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 C# \u043a\u043e\u0434\u0430, \u043d\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 Linux\/MacOS \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043f\u043e\u0432\u043e\u0434\u043e\u043c \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0442\u0430\u043b <a href=\"https:\/\/github.com\/AvaloniaUI\/avaloniaui.net\/issues\/128\">issue<\/a> \u043a \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0410\u0432\u0430\u043b\u043e\u043d\u0438\u0438 \u043d\u0430 Github. <\/p>\n<p>  <\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0434\u0435\u043b\u0430\u043d \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/reactiveui.net\/\">ReactiveUI<\/a> \u0438 \u0432 issue \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 MVVM \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0435\u0437 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u0418\u043c\u0435\u043d\u043d\u043e \u0434\u0430\u043d\u043d\u0443\u044e \u0446\u0435\u043b\u044c \u043f\u0440\u0435\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f.<\/p>\n<p>  <\/p>\n<h2 id=\"mvvm-v-teorii\">MVVM \u0432 \u0442\u0435\u043e\u0440\u0438\u0438<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 (<a href=\"https:\/\/habr.com\/ru\/post\/338518\/\">1<\/a>,<a href=\"https:\/\/habr.com\/ru\/post\/176867\/\">2<\/a>) \u0438 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/enterprise-application-patterns\/mvvm\">Xamarin.Forms<\/a>, <a href=\"https:\/\/avaloniaui.net\/docs\/quickstart\/mvvm\">Avalonia<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u0434\u0435\u043b \u0432\u044b\u043d\u0435\u0441\u0435\u043d \u0432 \u0441\u043f\u043e\u0439\u043b\u0435\u0440.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u043e MVVM<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>MVVM (Model-View-ViewModel) \u2013 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0414\u0430\u043d\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445 WPF\/UWP\/Xamarin.<\/p>\n<p>  <\/p>\n<h3 id=\"chto-ot-chego-otdelyaet\">\u201c\u0427\u0442\u043e\u201d \u043e\u0442 \u201c\u0447\u0435\u0433\u043e\u201d \u043e\u0442\u0434\u0435\u043b\u044f\u0435\u0442?<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0430 \u0441\u043b\u043e\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0411\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 \u043f\u0435\u0440\u0432\u0430\u044f \u0431\u0443\u043a\u0432\u0430 \u201cM\u201d (<strong>Model<\/strong>). \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u043e\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, API, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0442.\u043f. \u0427\u0430\u0441\u0442\u043e \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432\u044b\u0434\u0435\u043b\u044f\u044e\u0442 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u0434-\u0447\u0430\u0441\u0442\u044c (Services). <\/li>\n<li>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u2013 \u0432 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 \u0431\u0443\u043a\u0432\u0430 V (<strong>View<\/strong>) \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044f\u0437\u044b\u043a\u0430 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438 XAML. <\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0438 \u0434\u0432\u0430 \u0441\u043b\u043e\u044f \u0438 \u043f\u0440\u0438\u0437\u0432\u0430\u043d \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0435\u0449\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u2013 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (<strong>ViewModel<\/strong>).<\/p>\n<p>  <\/p>\n<p>ViewModel \u2014 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043b\u043e\u0439 \u043c\u0435\u0436\u0434\u0443 Model \u0438 View \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 (Binding). \u0414\u043b\u044f \u043f\u043e\u043d\u044f\u0442\u0438\u044f Binding, \u0432\u0432\u0435\u0434\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 (Property) \u2013 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u043f\u043e\u043b\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043e ViewModel. \u041f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e binding, \u0432\u0441\u0435 property, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 ViewModel \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f View. \u0412\u0430\u0436\u043d\u044b\u043c, \u0442\u0430\u043a\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c<\/strong> property \u2013 \u043f\u043e\u0434 \u044d\u0442\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442, \u0447\u0442\u043e \u043b\u044e\u0431\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043e View \u0438\u043b\u0438 Model \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 &quot;\u0443\u0437\u043d\u0430\u0435\u0442&quot; ViewModel \u0431\u0443\u0434\u0443\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u0440\u0438\u0448\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 (\u0432\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 API \u0438 \u0442.\u043f)<br \/>  \u041a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: <\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ar\/ff\/x7\/arffx7y_xq1g8tjmp2micomhuja.png\"\/><\/p>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (View. ViewModel, Model, binding, property). \u0421\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043c\u043d\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0430, \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0435, \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u043f\u0440\u0438\u0432\u044b\u0447\u043a\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<h3 id=\"zachem-razdelyat\">\u0417\u0430\u0447\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c?<\/h3>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f MVVM, \u0432\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0435, \u0447\u0442\u043e \u0441\u043b\u043e\u0439 Model \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e View, \u044d\u0442\u043e \u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u043e \u0434\u043b\u044f ViewModel. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u044d\u0442\u043e \u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430: <\/p>\n<p>  <\/p>\n<ul>\n<li>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u043e\u0436\u0434\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u0434\u0440\u0443\u0433\/\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445, \u0438\u0437\u043c\u0435\u043d\u044f\u044f \u0442\u043e\u043b\u044c\u043a\u043e View. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Android \/ iOS \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Xamarin \u0438 \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0435\u0441\u043a\u0442\u043e\u043f \u0432\u0435\u0440\u0441\u0438\u044e. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f MVVM, \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 View, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445 WPF\/UWP. \u041d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u043f\u0438\u0441\u0430\u043d <a href=\"https:\/\/habr.com\/ru\/post\/418007\/\">\u0442\u0443\u0442<\/a> \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 MVVM.<\/li>\n<li>Unit-\u0442\u0435\u0441\u0442\u044b. \u041d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c Model \u0438 ViewModel \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c Unit-\u0442\u0435\u0441\u0442\u044b, \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. <\/li>\n<li>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0435\u0434\u0438\u0437\u0430\u0439\u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u2013 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442. <\/li>\n<\/ul>\n<\/div><\/div>\n<p>  <\/p>\n<h2 id=\"praktika\">\u041f\u0440\u0430\u043a\u0442\u0438\u043a\u0430<\/h2>\n<p>  <\/p>\n<p>\u0417\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0438\u0434\u0435\u044e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0444\u0438\u043b\u044c\u043c\u043e\u0432. \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438: <\/p>\n<p>  <\/p>\n<ol>\n<li>\u041e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u043c\u044b;<\/li>\n<li>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043d\u0430\u0431\u043e\u0440\u0430\u043c\u0438 \u0444\u0438\u043b\u044c\u043c\u043e\u0432;<\/li>\n<li>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434 MVVM.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u043c \u0441 WPF\/UWP\/Xamarin \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0437\u0430\u0434\u0443\u043c\u043a\u0438 \u0431\u044b\u043b\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u043a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0430 \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0438 \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u043b\u043e \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u044e\u0430\u043d\u0441\u043e\u0432 \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432, \u0438 \u0446\u0435\u043b\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u0440\u0430\u0437\u043c\u044b\u0432\u0430\u043b\u0430\u0441\u044c. <\/p>\n<p>  <\/p>\n<h3 id=\"instrumenty-razrabotki\">\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/h3>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0412\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f <a href=\"https:\/\/visualstudio.microsoft.com\/ru\/\">Visual Studio<\/a> \u0438 \u043f\u043b\u0430\u0433\u0438\u043d <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio\">Avalonia<\/a> \u0434\u043b\u044f \u043d\u0435\u0435.<br \/>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e <a href=\"https:\/\/avaloniaui.net\/docs\/quickstart\/create-new-project\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>, Avalonia \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 .Net Framework \u0438 Net Core 2.0+. \u0414\u043b\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c Net Core. \u0414\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043b\u0430\u0433\u0438\u043d \u0431\u044b\u043b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 Visual Studio 2019, \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet-core\/3.0\">Net Core 3.0<\/a>. \u0412\u044b\u0431\u043e\u0440 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Avalonia \u0432 Visual Studio 2019:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ub\/s4\/sg\/ubs4sgu98tiv5n2k0tezpsnjtmi.png\"\/><\/p>\n<p>  <\/p>\n<h3 id=\"nachalnyy-vid-proekta-dobavlenie-stiley-i-dannyh\">\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0438\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0438\u043b\u0435\u0439 \u0438 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 Avalonia \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/gj\/-a\/bk\/gj-abkzub5fxb8iitykofh2u7ay.png\"\/><\/p>\n<p>  <\/p>\n<p><strong>Program.cs<\/strong> \u2013 \u0432 \u043d\u0435\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f Main \u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412 \u043d\u0435\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e Application \u043a\u043b\u0430\u0441\u0441 App. \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0434\u0432\u0443\u0445 \u0444\u0430\u0439\u043b\u0430\u0445:<br \/>  <strong>App.xaml<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u2013 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 \u043a\u043b\u0430\u0441\u0441 Application.<br \/>  <strong>App.xaml.cs<\/strong> \u2013 code-behind \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f xaml \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0441 \u043d\u0435\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f MainWindow.<br \/>  <strong>MainWindow<\/strong> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043b\u0430\u0441\u0441\u0430 Window, \u0432 code-behind \u0444\u0430\u0439\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (\u043a\u043b\u0438\u043a\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0438, \u0432\u044b\u0431\u043e\u0440 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0438 \u0442.\u043f) \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432 MainWindow.xaml.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0443 \u043d\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043e\u043a\u043d\u043e \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u201cWelcome to Avalonia\u201d.<\/p>\n<p>  <\/p>\n<h4 id=\"dobavlenie-stiley\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0438\u043b\u0435\u0439<\/h4>\n<p>  <\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0430\u043c\u0438\u0445 \u0441\u0442\u0438\u043b\u0435\u0439 \u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <a href=\"https:\/\/github.com\/speeedforce\/Moviewer\/tree\/master\/MovieApp.Styling\">\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443<\/a> (\u0430\u0432\u0442\u043e\u0440\u0441\u043a\u0430\u044f) \u0432 \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 <strong>\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c<\/strong> \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0410\u0432\u0430\u043b\u043e\u043d\u0438\u0438. \u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0442\u0438\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 MainWindow.xaml \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">&lt;Window xmlns=&quot;https:\/\/github.com\/avaloniaui&quot;         xmlns:x=&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml&quot;         xmlns:d=&quot;http:\/\/schemas.microsoft.com\/expression\/blend\/2008&quot;         xmlns:mc=&quot;http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006&quot;         mc:Ignorable=&quot;d&quot; d:DesignWidth=&quot;800&quot; d:DesignHeight=&quot;450&quot;         x:Class=&quot;Moviewer.MainWindow&quot;         Title=&quot;Moviewer&quot;&gt;   &lt;Window.Styles&gt;     &lt;StyleInclude Source=&quot;avares:\/\/Moviewer.Styling\/AppStyle.xaml&quot;\/&gt;   &lt;\/Window.Styles&gt;    Welcome to Avalonia! &lt;\/Window&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0442\u0438\u043b\u0435\u0439, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0445\u0435\u0434\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">&lt;Window xmlns=&quot;https:\/\/github.com\/avaloniaui&quot;         xmlns:x=&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml&quot;         xmlns:d=&quot;http:\/\/schemas.microsoft.com\/expression\/blend\/2008&quot;         xmlns:mc=&quot;http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006&quot;         mc:Ignorable=&quot;d&quot; d:DesignWidth=&quot;800&quot; d:DesignHeight=&quot;450&quot;         x:Class=&quot;Moviewer.MainWindow&quot;         Title=&quot;Moviewer&quot;&gt;   &lt;Window.Styles&gt;     &lt;StyleInclude Source=&quot;avares:\/\/Moviewer.Styling\/AppStyle.xaml&quot;\/&gt;   &lt;\/Window.Styles&gt;    &lt;Grid RowDefinitions=&quot;Auto, *&quot; Classes=&quot;mainContainer&quot;&gt;     &lt;Border Classes=&quot;header&quot; Grid.Row=&quot;0&quot;&gt;       &lt;StackPanel Classes=&quot;title&quot;&gt;         &lt;TextBlock Classes=&quot;title&quot;&gt; MO &lt;\/TextBlock&gt;         &lt;TextBlock Classes=&quot;titleYellow&quot;&gt; VIEW &lt;\/TextBlock&gt;         &lt;TextBlock Classes=&quot;title&quot;&gt; ER &lt;\/TextBlock&gt;       &lt;\/StackPanel&gt;     &lt;\/Border&gt;   &lt;\/Grid&gt; &lt;\/Window&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u043e\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/vz\/gq\/ux\/vzgquxoehnn8zhpxyec6g51dcck.png\"\/><\/p>\n<p>  <\/p>\n<h4 id=\"dobavlyaem-dannye\">\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435<\/h4>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438 \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u043d\u0430 <a href=\"https:\/\/github.com\/speeedforce\/Moviewer\/tree\/master\/Moviewer\/Data\">GitHub<\/a>. \u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Moviewer \u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 Moviewer.csproj \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">  &lt;ItemGroup&gt;     &lt;None Update=&quot;Data\\**\\*\\*&quot;&gt;       &lt;CopyToOutputDirectory&gt;Always&lt;\/CopyToOutputDirectory&gt;     &lt;\/None&gt;   &lt;\/ItemGroup&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0432 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043f\u043a\u0443. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0439\u0442\u0438 \u043f\u0430\u043f\u043a\u0443 \u0432 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u043f\u0443\u0442\u0438: project-folder\/bin\/netcoreapp3.0\/Data. <\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/gl\/hm\/cs\/glhmcsmjhbej20gqk4wntbdm3nm.png\"\/><\/p>\n<p>  <\/p>\n<p>\u0424\u043e\u0440\u043c\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/oz\/bd\/bh\/ozbdbh8rdda7p0z8_nhmmybs79g.png\"\/><\/p>\n<p>  <\/p>\n<h2 id=\"realizuem-mvvm\">\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c MVVM<\/h2>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u043f\u043a\u0443 ViewModels \u0438 \u043a\u043b\u0430\u0441\u0441\u044b ViewModelBase, MainWindowViewModel.cs \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ViewModel \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 INotifyPropertyChanged. \u0414\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 Property, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0432 ViewModel. \u0412 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e ViewModel, \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 ViewModelBase, \u0430 \u0432 ViewModel \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e ViewModelBase.<\/p>\n<p>  <\/p>\n<p><strong><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/em><\/strong>: \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a (<a href=\"http:\/\/www.mvvmlight.net\/\">MVVMLight<\/a>, <a href=\"https:\/\/prismlibrary.com\/docs\/\">Prism<\/a>, <a href=\"https:\/\/reactiveui.net\/\">ReactiveUI<\/a>, <a href=\"https:\/\/www.mvvmcross.com\/documentation\/\">MVVM Cross<\/a>), \u0433\u0434\u0435 \u0448\u0430\u0433\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0432 \u0446\u0435\u043b\u043e\u043c. \u0414\u043b\u044f \u0410\u0432\u0430\u043b\u043e\u043d\u0438\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c ReactiveUI.<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">    public class ViewModelBase : INotifyPropertyChanged     {         public event PropertyChangedEventHandler PropertyChanged;          protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)         {             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));         }     }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 MainWindowViewModel.cs \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c binding \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 View \u0438 ViewModel.<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">    public class MainWindowViewModel : ViewModelBase     {         public string Text =&gt; &quot;Welcome to Avalonia&quot;;     }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0432 MainWindow.xaml \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u0442\u044d\u0433\u043e\u043c Grid.<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">  &lt;StackPanel Grid.Row=&quot;1&quot;&gt;       &lt;TextBlock Text=&quot;{Binding Text, Mode=OneWay}&quot;\/&gt;   &lt;\/StackPanel&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0448\u0430\u0433, \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u043e\u0440\u043c\u0443 \u0441 ViewModel. \u0412 \u0444\u0430\u0439\u043b\u0435 App.xaml.cs, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c DataContext \u0434\u043b\u044f MainWindow.<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">        public override void OnFrameworkInitializationCompleted()         {             if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)             {                 desktop.MainWindow = new MainWindow()                 {                     DataContext = new MainWindowViewModel()                 };             }              base.OnFrameworkInitializationCompleted();         }<\/code><\/pre>\n<p>  <\/p>\n<p>DataContext \u2013 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 MainWindowViewModel. \u0412 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u043e\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a: \u201cproperty \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 MainWindowViewModel, <strong>\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b<\/strong> \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u0432 MainWindow.xaml\u201d<br \/>  \u0412 MainWindow.xaml \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e binding \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u043d\u0430\u0448\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0438\u0437 MainWindowViewModel. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u201cWelcome to Avalonia\u201d \u0432 \u043b\u0435\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443.<br \/>  \u041e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0435\u0441\u0442\u044c \u0432 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u0435 \u0432\u044b\u0448\u0435, \u0430 \u043e DataContext \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c <a href=\"https:\/\/rachel53461.wordpress.com\/2012\/07\/14\/what-is-this-datacontext-you-speak-of\/\">\u0431\u043b\u043e\u0433\u0435<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"realizaciya-model\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Model<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c: \u043a\u043b\u0430\u0441\u0441 \u0444\u0438\u043b\u044c\u043c\u0430<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">    public class Movie     {         public int Id { get; set; }         public int VoteCount { get; set; }         public string PosterPath { get; set; }         public string Title { get; set; }         public double VoteAverage { get; set; }         public string Overview { get; set; }         public string ReleaseDate { get; set; }          [JsonIgnore]         public Bitmap Poster { get; set; }     }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0444\u0438\u043b\u044c\u043c\u0430\u0445. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0430\u043f\u043a\u0443 Services \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 json \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.nuget.org\/packages\/Newtonsoft.Json\/\">Newtonsoft.Json<\/a> <\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">    public class MovieService     {         readonly string _workingDirectory = Environment.CurrentDirectory;         public async Task&lt;IEnumerable&lt;Movie&gt;&gt; GetMovies(int pageIndex)         {             var folderPath = $&quot;{_workingDirectory}\\\\Data\\\\Page{pageIndex}&quot;;             var dataFile = $&quot;page{pageIndex}.json&quot;;             var imageFolder = Path.Combine(folderPath, &quot;Images&quot;);             List&lt;Movie&gt; items;              \/\/read data             using (var r = new StreamReader(Path.Combine(folderPath, dataFile)))             {                 var json = r.ReadToEnd();                 items = JsonConvert.DeserializeObject&lt;List&lt;Movie&gt;&gt;(json);             }              \/\/load images             foreach (var item in items)             {                 var imagePath = Path.Combine(imageFolder, $&quot;{item.Title}.png&quot;);                 item.Poster = await GetPoster(imagePath);             }             return items;         }         private Task&lt;Bitmap&gt; GetPoster(string posterUrl)         {             return Task.Run(() =&gt;             {                 using var fileStream = new FileStream(posterUrl, FileMode.Open, FileAccess.Read) {Position = 0};                 var bitmap = new Bitmap(fileStream);                 return bitmap;             });         }      }  <\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 GetMovies \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0444\u0438\u043b\u044c\u043c\u0430\u0445, \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f GetPoster. \u041d\u0430 \u044d\u0442\u043e\u043c \u043b\u043e\u0433\u0438\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430, \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c ViewModel \u0438 View \u0438 \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0438\u043b\u044c\u043c\u043e\u0432.<\/p>\n<p>  <\/p>\n<h2 id=\"obnovlenie-viewmodel-i-view\">\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 ViewModel \u0438 View<\/h2>\n<p>  <\/p>\n<p>GetMovie \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 Task, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c NotifyTaskCompletion \u0438\u0437 <a href=\"https:\/\/www.nuget.org\/packages\/Nito.AsyncEx\/3.0.1\">Nito.AsyncEx 3.0.1<\/a> (<strong>\u0412\u0430\u0436\u043d\u043e<\/strong> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u0441\u0438\u044e 3.0.1). \u041e \u0442\u043e\u043c \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0432 ViewModel \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0432 <a href=\"https:\/\/blog.stephencleary.com\/2013\/01\/async-oop-2-constructors.html\">\u0431\u043b\u043e\u0433\u0435<\/a> \u0421\u0442\u0438\u0432\u0435\u043d\u0430 \u041a\u043b\u0435\u0440\u0438.<br \/>  \u041b\u043e\u0433\u0438\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u0440\u043e\u0441\u0442\u0430: \u043f\u043e\u043a\u0430 \u0433\u0440\u0443\u0437\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c ProgressBar, \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d.<br \/>  <strong><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/em><\/strong>: \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0442\u043e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0435\u0435 \u0441\u0430\u043c\u0438 (\u043d\u0430 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0443) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Task.Delay(1000).<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">    public class MainWindowViewModel : ViewModelBase     {         private MovieService _movieService;         public MainWindowViewModel()         {             InitializationNotifier = NotifyTaskCompletion.Create(InitializeAsync());         }          public INotifyTaskCompletion InitializationNotifier { get; private set; }          private async Task InitializeAsync()         {             _movieService = new MovieService();             var data = await _movieService.GetMovies(1);         await Task.Delay(1000);             MyItems = new ObservableCollection&lt;Movie&gt;(data);         }          private ObservableCollection&lt;Movie&gt; _myItems;         public ObservableCollection&lt;Movie&gt; MyItems         {             get =&gt; _myItems;             set             {                 if (value != null)                 {                     _myItems = value;                     OnPropertyChanged();                 }             }         }     } } <\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u0432\u0435\u0434\u0435\u043c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0444\u0438\u043b\u044c\u043c\u044b, \u0437\u0430\u043c\u0435\u043d\u0438\u0432 StackPanel \u0432 MainWindows.xaml \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">     &lt;Grid Classes=&quot;contentContainer&quot; Grid.Row=&quot;1&quot;&gt;       &lt;ProgressBar           VerticalAlignment=&quot;Center&quot;           HorizontalAlignment=&quot;Center&quot;           IsVisible=&quot;{Binding InitializationNotifier.IsNotCompleted}&quot;           Classes=&quot;progressBar&quot; IsIndeterminate=&quot;True&quot;\/&gt;        &lt;ListBox Classes=&quot;movies&quot;         Grid.Column=&quot;1&quot; Grid.Row=&quot;1&quot;         IsVisible=&quot;{Binding InitializationNotifier.IsCompleted, Mode=TwoWay}&quot;         ScrollViewer.HorizontalScrollBarVisibility=&quot;Disabled&quot;         Items=&quot;{Binding MyItems}&quot;&gt;         &lt;ListBox.ItemTemplate&gt;           &lt;DataTemplate&gt;             &lt;Grid&gt;               &lt;Grid.RowDefinitions&gt;                 &lt;RowDefinition Height=&quot;*&quot;\/&gt;                 &lt;RowDefinition Height=&quot;Auto&quot; MinHeight=&quot;48&quot;\/&gt;               &lt;\/Grid.RowDefinitions&gt;               &lt;Image Grid.Row=&quot;0&quot; Stretch=&quot;UniformToFill&quot; Source=&quot;{Binding Poster}&quot;\/&gt;               &lt;Border Grid.Row=&quot;1&quot; Classes=&quot;title&quot;&gt;                 &lt;Grid ColumnDefinitions=&quot;*, 0.4*&quot; Margin=&quot;4&quot;&gt;                   &lt;TextBlock FontSize=&quot;18&quot; Text=&quot;{Binding Title}&quot; \/&gt;                   &lt;TextBlock FontSize=&quot;24&quot; Grid.Column=&quot;1&quot; Text=&quot;{Binding VoteAverage}&quot;\/&gt;                 &lt;\/Grid&gt;               &lt;\/Border&gt;             &lt;\/Grid&gt;           &lt;\/DataTemplate&gt;         &lt;\/ListBox.ItemTemplate&gt;         &lt;ListBox.ItemsPanel&gt;           &lt;ItemsPanelTemplate&gt;             &lt;WrapPanel ItemWidth=&quot;340&quot; ItemHeight=&quot;480&quot; Orientation=&quot;Horizontal&quot;\/&gt;           &lt;\/ItemsPanelTemplate&gt;         &lt;\/ListBox.ItemsPanel&gt;       &lt;\/ListBox&gt;     &lt;\/Grid&gt; <\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f ProgressBar, \u0430 \u0437\u0430\u0442\u0435\u043c \u043d\u0430\u0431\u043e\u0440 \u0444\u0438\u043b\u044c\u043c\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/i7\/ro\/tk\/i7rotksfpdehy1_0ekodjgu6edy.gif\"\/><\/p>\n<p>  <\/p>\n<h3 id=\"pereklyuchaem-nabory-filmov\">\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043d\u0430\u0431\u043e\u0440\u044b \u0444\u0438\u043b\u044c\u043c\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0412 ViewModel \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b Page, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u0432\u0432\u0435\u0440\u0445\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 PropertyChange \u0438 \u201c\u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u0435\u0442\u201d \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044f \u043d\u0443\u0436\u043d\u044b\u0439 property:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">        private int _page;         public int Page         {             get =&gt; _page;             set             {                 _page = value;                 OnPropertyChanged();             }         }<\/code><\/pre>\n<p>  <\/p>\n<p><strong><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/em><\/strong>: \u0432 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a (<a href=\"https:\/\/github.com\/Fody\/PropertyChanged\">Fody<\/a>, <a href=\"https:\/\/reactiveui.net\/docs\/handbook\/view-models\/boilerplate-code#read-write-properties\">ReactiveUI<\/a>) \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u043e \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u0435\u0435.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f: \u0432\u043f\u0435\u0440\u0435\u0434, \u043d\u0430\u0437\u0430\u0434 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412 \u043d\u0438\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c GetMovie \u0441 \u043d\u043e\u0432\u044b\u043c \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c. \u041b\u043e\u0433\u0438\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u043e \u0442\u043e\u0439, \u0447\u0442\u043e \u0438 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0441\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">         public async Task LoadData(int page)         {             var data = await _movieService.GetMovies(page);             await Task.Delay(1000);             MyItems = new ObservableCollection&lt;Movie&gt;(data);         }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f ViewModel \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">        private async Task InitializeAsync()         {             Page = 1;             _movieService = new MovieService();             await LoadData(Page);         }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">        public void NextPage()         {             if (_page+1 &gt; 10)                 Page = 1;               else                 Page = _page + 1;              InitializationNotifier = NotifyTaskCompletion.Create(LoadData(Page));         }          public void PrevPage()         {             if (1 &gt; _page - 1)                 Page = 10;             else                 Page = _page - 1;              InitializationNotifier = NotifyTaskCompletion.Create(LoadData(Page));         } <\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. \u0414\u043e\u0439\u0434\u044f \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 1 \u0438 \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443. \u041d\u0430\u0436\u0438\u043c\u0430\u044f \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 Prev \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439, \u043c\u044b \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 MVVM \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b (<a href=\"https:\/\/habr.com\/ru\/post\/196960\/\">Commands<\/a>). \u0412 \u0410\u0432\u0430\u043b\u043e\u043d\u0438\u0438 \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 XAML \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c, \u043d\u043e \u0438 \u043a <a href=\"https:\/\/avaloniaui.net\/docs\/binding\/binding-to-commands\">\u043c\u0435\u0442\u043e\u0434\u0430\u043c<\/a> (\u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435), \u0447\u0442\u043e \u043f\u043e\u0440\u043e\u0439 \u0443\u0434\u043e\u0431\u043d\u0435\u0435, \u0447\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/a6\/vx\/p-\/a6vxp-jkeefdcs0frk7rhdyhz-g.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u0442 \u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434, \u0447\u0442\u043e \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ViewModel, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e NotifyTaskCompletion. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b ProgressBar \u043f\u043e\u044f\u0432\u043b\u044f\u043b\u0441\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e InitializationNotifier \u0441\u0434\u0435\u043b\u0430\u0442\u044c property, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 OnPropertyChange():<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">        private INotifyTaskCompletion _initializationNotifier;         public INotifyTaskCompletion InitializationNotifier         {             get =&gt; _initializationNotifier;             private set             {                 _initializationNotifier = value;                 OnPropertyChanged();             }         }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/avaloniaui.net\/docs\/controls\/grid\">Grid<\/a> \u0441 2-\u043c\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 3-\u043c\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0430\u043c\u0438. \u041f\u043e\u0441\u043b\u0435 Grid.Row = \u201c1\u201d \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 (\u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u044d\u0433 &gt; \u0431\u044b\u043b \u043f\u043e\u0441\u043b\u0435 \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u0447\u0435\u043a):<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">ColumnDefinitions=&quot;Auto, *, Auto&quot; RowDefinitions=&quot;Auto, *&quot; &gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u043c ProgressBar \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 <\/p>\n<p>  <\/p>\n<pre><code class=\"xml\"> Grid.Column=&quot;1&quot; Grid.Row=&quot;1&quot; <\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 MainWindow \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0441\u0432\u044f\u0436\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438. <\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">      &lt;TextBlock Grid.Column=&quot;1&quot;                  HorizontalAlignment=&quot;Center&quot;                  Margin=&quot;4&quot;                  FontSize=&quot;18&quot;                  FontWeight=&quot;Bold&quot;                  Foreground=&quot;#819FFF&quot;                  Text=&quot;{Binding Path=Page}&quot;\/&gt;        &lt;Button Command=&quot;{Binding PrevPage}&quot;         Grid.Row=&quot;1&quot; Grid.Column=&quot;0&quot;         Content=&quot;PREV&quot;         Classes=&quot;navigation&quot;&gt;       &lt;\/Button&gt;        &lt;Button Command=&quot;{Binding NextPage}&quot;             Grid.Row=&quot;1&quot; Grid.Column=&quot;2&quot;             Content=&quot;NEXT&quot;             Classes=&quot;navigation&quot;&gt;       &lt;\/Button&gt; <\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043e! \u0410\u0432\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u043e\u0441\u044c \u043d\u0430 Windows 10, Mint. <\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/m1\/l0\/kh\/m1l0khsdkqdhwns-ppnxs5jwq_w.jpeg\"\/><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/st\/vs\/nu\/stvsnu3rnwr4jii95utubzpl4n0.jpeg\"\/><\/p>\n<p>  <\/p>\n<h2 id=\"kak-zapustit-na-linux\">\u041a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 Linux<\/h2>\n<p>  <\/p>\n<p>\u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Net Core, \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043f\u043a\u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 dotnet Moviewer.dll (\u0438\u043b\u0438 \u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0412\u044b \u0443\u043a\u0430\u0436\u0435\u0442\u0435 \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430)<\/p>\n<p>  <\/p>\n<h2 id=\"mnenie-avtora-pro-avalonia\">\u041c\u043d\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0430 \u043f\u0440\u043e Avalonia<\/h2>\n<p>  <\/p>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u044b\u043b\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u043f\u0430\u0441\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445 \u0431\u0443\u0434\u0435\u0442 \u00ab\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u044b\u043c\u00bb \u0438 \u0447\u0442\u043e-\u0442\u043e \u00ab\u043f\u043e\u0435\u0434\u0435\u0442, \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f\u00bb. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0441\u0431\u043e\u0440\u043e\u043a, \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043d\u0443 \u0438 \u0441\u043b\u0435\u0433\u043a\u0430 \u0441\u0442\u0435\u0440\u0435\u043e\u0442\u0438\u043f\u043d\u043e\u0435 \u201c UI \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430 Net \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f Windows\u201d. \u041f\u0440\u0438\u044f\u0442\u043d\u044b\u043c \u0443\u0434\u0438\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u0430\u043b \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0434\u0432\u0430 \u0448\u0430\u0433\u0430 \u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043c\u0435\u043d\u044f\u0442\u044c. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0435\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u2013 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u043d\u0430: \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u044b, \u043e\u0431\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0443\u0442\u0438, \u0430 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c\u0438, \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435 \u0431\u044b\u043b\u043e \u0433\u043b\u0430\u0434\u043a\u043e. <\/p>\n<p>  <\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e Avalonia \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0438\u043b\u0435\u0439 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 css. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u0430\u043d\u043d\u044b\u0439 \u0430\u0441\u043f\u0435\u043a\u0442 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0441\u044f. \u0412 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0432 WPF\/UWP. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e \u0441\u0442\u0438\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u0442\u0430\u0442\u044c\u044f\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/471046\/\">\u0421\u0442\u0438\u043b\u044c\u043d\u0430\u044f \u0410\u0432\u0430\u043b\u043e\u043d\u0438\u044f<\/a>;<\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/487000\/\">Citrus: \u041d\u0430\u0431\u043e\u0440 \u0441\u0442\u0438\u043b\u0435\u0439 \u0434\u043b\u044f Avalonia<\/a>;<\/li>\n<li><a href=\"https:\/\/medium.com\/swlh\/cross-platform-gui-for-dotnet-applications-bbd284709600?source=friends_link&amp;sk=8eca17f8d324b3c6c7b90bb777a9be2d\">A Cross-Platform GUI Theme for Desktop .NET Core Applications<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0418\u0437 \u043c\u0438\u043d\u0443\u0441\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0441 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c \u0434\u043b\u044f Visual Studio, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043d\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u0440\u0435\u0432\u044c\u044e\u0435\u0440. \u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 Linux, \u043d\u043e \u0431\u0435\u0437 \u043d\u0435\u0433\u043e. \u0421\u0435\u0439\u0447\u0430\u0441 \u0443\u0441\u0438\u043b\u0438\u044f\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 (<a href=\"https:\/\/habr.com\/ru\/users\/fornever\/\" class=\"user_link\">ForNeVeR<\/a>) \u043a Rider \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u0435\u0442 <a href=\"https:\/\/github.com\/ForNeVeR\/AvaloniaRider\">\u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f<\/a> \u043b\u044e\u0431\u043e\u0439 \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0435\u043c \u0412\u0430\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0430, \u0438 \u0412\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0432 \u043d\u0435\u0439. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0434\u0440\u0443\u0437\u044c\u044f\u043c \u0438 \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c, \u043a\u0430\u043a \u043f\u0435\u0440\u0432\u044b\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430\u043c; <\/li>\n<li><a href=\"https:\/\/t.me\/Avalonia\">\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0443 \u0410\u0432\u0430\u043b\u043e\u043d\u0438\u0438 \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c<\/a>. <\/li>\n<li>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c <a href=\"https:\/\/habr.com\/ru\/users\/larymar\/\" class=\"user_link\">Larymar<\/a> \u0438 <a href=\"https:\/\/habr.com\/ru\/users\/worldbeater\/\" class=\"user_link\">worldbeater<\/a> \u0437\u0430 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438.<\/li>\n<\/ul>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/505036\/\"> https:\/\/habr.com\/ru\/post\/505036\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/505036\/\">\n<h2 id=\"avalonia-eto\">Avalonia \u044d\u0442\u043e?<\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/avaloniaui.net\/docs\">Avalonia<\/a> \u2013 \u044d\u0442\u043e \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 XAML \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b .Net. \u0414\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043d\u0430 WPF\/UWP\/Xamarin \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0435\u043d \u0438 \u043f\u0440\u043e\u0441\u0442 \u0432 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0438. Avalonia \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 Windows, Linux, macOS, \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u0430 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Android \u0438 iOS. \u0420\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f open-source. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-304704","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/304704","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=304704"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/304704\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=304704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=304704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=304704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}