{"id":405202,"date":"2024-06-29T18:10:57","date_gmt":"2024-06-29T18:10:57","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=405202"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=405202","title":{"rendered":"<span>Unity: \u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 ListView \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438?<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 ListView c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/64a9671c53324501d3e965f4\" data-style=\"\" id=\"64a9671c53324501d3e965f4\" width=\"\"><\/div>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/unity.com\/features\/ui-toolkit\" rel=\"noopener noreferrer nofollow\">Unity UI Toolkit<\/a> \u0432 \u043f\u0430\u0440\u0435 \u0441 <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit\" rel=\"noopener noreferrer nofollow\">UnityMvvmToolkit<\/a>. \u042f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b \u043f\u0440\u043e UnityMvvmToolkit \u0441\u0442\u0430\u0442\u044c\u044e \u0432\u043e\u0442 <a href=\"https:\/\/habr.com\/ru\/articles\/689134\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u0421 \u0442\u0435\u0445 \u043f\u043e\u0440 API \u043f\u0440\u0438\u0442\u0435\u0440\u043f\u0435\u043b \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435, \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043f\u043b\u044e\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0434\u0430\u0439\u0442\u0435 \u0437\u043d\u0430\u0442\u044c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u043d\u0430\u043f\u0438\u0448\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043f\u043e \u043d\u0435\u0439.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0441\u043f\u0438\u0441\u043e\u043a \u0443 \u043d\u0430\u0441 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439, \u043c\u044b \u043f\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u0422\u0430\u043a\u0436\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0445\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0421\u043f\u0438\u0441\u043e\u043a \u0443 \u043d\u0430\u0441 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439, \u0430 \u0432\u043e\u0442 \u043f\u0430\u043c\u044f\u0442\u044c, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435\u0442.<\/p>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 ListView \u0432 Unity UI Toolkit \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0447\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043d\u0430\u043c \u0440\u0430\u0431\u043e\u0442\u0443. \u041e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435.<\/p>\n<blockquote>\n<p>P.S. \u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u043d\u0438\u0436\u0435 \u043a\u043e\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 <a href=\"https:\/\/github.com\/LibraStack\/UnityUxmlGenerator\" rel=\"noopener noreferrer nofollow\">UnityUxmlGenerator<\/a> \u0438 <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit#source-code-generator\" rel=\"noopener noreferrer nofollow\">UnityMvvmToolkit.Generator<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u0431\u0430\u0432\u044f\u0442 \u043d\u0430\u0441 \u043e\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u0443\u0447\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d.<\/p>\n<\/blockquote>\n<blockquote>\n<p>P.P.S. \u0414\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit#unitymvvmtoolkit\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439<\/a> UnityMvvmToolkit. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit#watch-quick-start\" rel=\"noopener noreferrer nofollow\">Quick start<\/a>.<\/p>\n<\/blockquote>\n<h2>Reusable Items List<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f <code>ReusableItemsList<\/code>. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u043d\u0451\u043c. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0443\u0442: <code>IList&lt;T><\/code>, <code>IList<\/code>, <code>INotifyCollectionChanged<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>IList<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c <code>ReusableItemsList<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>itemsSource<\/code> \u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e <code>ListView<\/code>, \u0430 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0434\u0432\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 <code>BindableListView<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 UnityMvvmToolkit.<\/p>\n<pre><code class=\"cs\">public class ReusableItemsList&lt;T> : List&lt;T>, IList&lt;T>, IList, INotifyCollectionChanged {     private int _virtualCount;      public ReusableItemsList(IEnumerable&lt;T> items) : base(items)     {     }      public new T this[int index]     {         get         {             var itemsCount = base.Count;              return itemsCount == 0 ? default : base[index % itemsCount];         }     }      object IList.this[int index]     {         get => this[index];         set => throw new NotImplementedException();     }      public new int Count => base.Count + _virtualCount;      public event NotifyCollectionChangedEventHandler CollectionChanged;      public void AddVirtualItems(int count)     {         _virtualCount += count;         CollectionChanged?.Invoke(this, default);     } }<\/code><\/pre>\n<p>\u041f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u043d\u043e \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435 \u2013 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 <code>base[index % itemsCount]<\/code>. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 10 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 20, \u0442\u043e \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 10 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442 0, \u0430 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 15 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442 5. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u0442\u043e \u043f\u043e\u0434\u0432\u043e\u0445 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u0435\u043d. \u041d\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u0437\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u044b \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u2013 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 <code>base.Count + _virtualCount<\/code>. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445. \u042d\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>ListView<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043e\u0441\u044b \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u0435\u0442\u043e\u0434 <code>AddVirtualItems<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0438 <code>CollectionChanged<\/code> \u0443 \u043d\u0430\u0441 <code>NotifyCollectionChangedEventArgs<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>default<\/code>. \u042d\u0442\u043e \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<h2>Images ListView<\/h2>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BindableImageListView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0411\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>BindableListView&lt;TItemBindingContext, TCollection><\/code>, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0443\u043a\u0430\u0436\u0435\u043c <code>ReusableItemsList<\/code> \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0430\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<pre><code class=\"cs\">[BindableElement] public partial class BindableImageListView :     BindableListView&lt;ImagesItemViewModel, ReusableItemsList&lt;ImagesItemViewModel>> {     [BindableProperty(defaultValue: \"MaxBindIndex\")]     private IProperty&lt;int> _maxBindIndexProperty;      protected override void BindItem(VisualElement item, int index, ImagesItemViewModel imagesItem,         IObjectProvider objectProvider)     {         if (_maxBindIndexProperty.Value &lt; index)         {             _maxBindIndexProperty.Value = index;         }          imagesItem.StartImagesLoading(index);         base.BindItem(item, index, imagesItem, objectProvider);     }      protected override void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)     {     } }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <code>BindItem<\/code>. \u0418\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u2013 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f <code>_maxBindIndexProperty<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u041d\u0443 \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>StartImagesLoading<\/code> \u0443 \u043d\u0430\u0448\u0435\u0439 <code>ViewModel'\u0438<\/code> \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 <code>NotifyCollectionChangedEventArgs<\/code> \u0431\u0443\u0434\u0435\u0442 <code>null<\/code>, \u043d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>OnItemsCollectionChanged<\/code>. \u0415\u0433\u043e \u043c\u043e\u0436\u0435\u043c \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>VirtualizationController<\/code> \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>OnScroll<\/code> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u043e\u0441\u0443 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438.<\/p>\n<blockquote>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b <code>BindableElement<\/code> \u0438 <code>BindableProperty<\/code> \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<\/blockquote>\n<details class=\"spoiler\">\n<summary>BindableImageListView.Uxml.g.cs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">\/\/ &lt;auto-generated\/> #pragma warning disable #nullable enable  ...  namespace BindableUIElements {     partial class BindableImageListView     {         [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private string BindingMaxBindIndexPath { get; set; }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         public new class UxmlFactory : UxmlFactory&lt;BindableImageListView, UxmlTraits>         {         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         public new class UxmlTraits : BindableListView&lt;ImagesItemViewModel, ReusableItemsList&lt;ImagesItemViewModel>>.UxmlTraits         {             [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             private readonly UxmlStringAttributeDescription _bindingMaxBindIndexPath = new()                  { name = \"binding-max-bind-index-path\", defaultValue = \"MaxBindIndex\" };              [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             [ExcludeFromCodeCoverage]             public override void Init(VisualElement visualElement, IUxmlAttributes bag, CreationContext context)             {                 base.Init(visualElement, bag, context);                  var control = (BindableImageListView) visualElement;                 control.BindingMaxBindIndexPath = _bindingMaxBindIndexPath.GetValueFromBag(bag, context);             }         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>BindableImageListView.Bindings.g.cs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">\/\/ &lt;auto-generated\/> #pragma warning disable #nullable enable  ...  namespace BindableUIElements {     partial class BindableImageListView : IBindableElement     {         [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] private PropertyBindingData? _maxBindIndexBindingData;          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         [ExcludeFromCodeCoverage]         public override void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)         {             BeforeSetBindingContext(context, objectProvider);              base.SetBindingContext(context, objectProvider);              if (string.IsNullOrWhiteSpace(BindingMaxBindIndexPath) == false) { _maxBindIndexBindingData ??= StringExtensions.ToPropertyBindingData(BindingMaxBindIndexPath!); _maxBindIndexProperty = objectProvider.RentProperty&lt;int>(context, _maxBindIndexBindingData!); _maxBindIndexProperty!.ValueChanged += OnMaxBindIndexPropertyValueChanged; }                  AfterSetBindingContext(context, objectProvider);         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         [ExcludeFromCodeCoverage]         public override void ResetBindingContext(IObjectProvider objectProvider)         {             BeforeResetBindingContext(objectProvider);              if (_maxBindIndexProperty != null) { _maxBindIndexProperty!.ValueChanged -= OnMaxBindIndexPropertyValueChanged; objectProvider.ReturnProperty(_maxBindIndexProperty); _maxBindIndexProperty = null; }              base.ResetBindingContext(objectProvider);              AfterResetBindingContext(objectProvider);         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private void OnMaxBindIndexPropertyValueChanged(object sender, int value) { OnMaxBindIndexPropertyValueChanged(value); }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void BeforeSetBindingContext(IBindingContext context, IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void AfterSetBindingContext(IBindingContext context, IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void BeforeResetBindingContext(IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void AfterResetBindingContext(IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] partial void OnMaxBindIndexPropertyValueChanged(int value);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>Image Info<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d <code>ImageInfoView.uxml<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 <code>ImagesItemView.uxml<\/code>.<\/p>\n<pre><code class=\"xml\">&lt;ui:UXML xmlns:uitk=\"UnityMvvmToolkit.UITK.BindableUIElements\" ...>     &lt;ui:VisualElement name=\"ElementsContainer\" usage-hints=\"MaskContainer\" class=\"container\">         &lt;BindableImage name=\"BindableImage\" binding-image-path=\"Image\" binding-is-visible-path=\"IsVisible\" usage-hints=\"DynamicTransform\" class=\"image image--animation image--init-position\" \/>         &lt;ui:VisualElement name=\"ImageInfoContainer\" usage-hints=\"GroupTransform\" class=\"image-info__container\">             &lt;uitk:BindableLabel name=\"AuthorLabel\" binding-text-path=\"Author\" class=\"image-info__label image-info__author-label\" \/>             &lt;ui:VisualElement name=\"ImageIdPanel\" style=\"flex-direction: row; align-items: center;\">                 &lt;uitk:BindableLabel name=\"ImageIdTitleLabel\" text=\"Id -\" class=\"image-info__label image-info__id-label\" style=\"margin-right: 0;\" \/>                 &lt;uitk:BindableLabel name=\"ImageIdValueLabel\" binding-text-path=\"Id\" class=\"image-info__label image-info__id-label\" \/>             &lt;\/ui:VisualElement>         &lt;\/ui:VisualElement>     &lt;\/ui:VisualElement> &lt;\/ui:UXML><\/code><\/pre>\n<p>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BindableImage<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u043b\u0430\u0432\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>IsVisible<\/code>.<\/p>\n<pre><code class=\"cs\">[BindableElement] public partial class BindableImage : AnimatedImage {     [BindableProperty(\"Image\")]     private IReadOnlyProperty&lt;Texture2D> _imageProperty;      [BindableProperty(\"IsVisible\")]     private IReadOnlyProperty&lt;bool> _isVisibleProperty;      partial void AfterSetBindingContext(IBindingContext context, IObjectProvider objectProvider)     {         SetImage(_imageProperty?.Value);         SetVisibility(_isVisibleProperty?.Value ?? false);     }      partial void AfterResetBindingContext(IObjectProvider objectProvider)     {         SetImage(default);         SetVisibility(false);     }      partial void OnImagePropertyValueChanged(Texture2D value)     {         SetImage(value);     }      partial void OnIsVisiblePropertyValueChanged(bool value)     {         SetVisibility(value);     }      private void SetVisibility(bool isVisible)     {         if (isVisible)         {             AnimateIn();         }         else         {             AnimateOut();         }     } }  [UxmlElement] public partial class AnimatedImage : VisualElement {     private const string ImageInitPositionClassName = \"image--init-position\";      protected void SetImage(Texture2D image)     {         style.backgroundImage = image;     }      protected void AnimateIn()     {         RemoveFromClassList(ImageInitPositionClassName);     }      protected void AnimateOut()     {         AddToClassList(ImageInitPositionClassName);     } }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>BindableImage.Uxml.g.cs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">\/\/ &lt;auto-generated\/> #pragma warning disable #nullable enable  ...  namespace BindableUIElements {     partial class BindableImage     {         [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private string BindingImagePath { get; set; }  [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private string BindingIsVisiblePath { get; set; }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         public new class UxmlFactory : UxmlFactory&lt;BindableImage, UxmlTraits>         {         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         public new class UxmlTraits : AnimatedImage.UxmlTraits         {             [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             private readonly UxmlStringAttributeDescription _bindingImagePath = new()                  { name = \"binding-image-path\", defaultValue = \"Image\" };  [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             private readonly UxmlStringAttributeDescription _bindingIsVisiblePath = new()                  { name = \"binding-is-visible-path\", defaultValue = \"IsVisible\" };              [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             [ExcludeFromCodeCoverage]             public override void Init(VisualElement visualElement, IUxmlAttributes bag, CreationContext context)             {                 base.Init(visualElement, bag, context);                  var control = (BindableImage) visualElement;                 control.BindingImagePath = _bindingImagePath.GetValueFromBag(bag, context); control.BindingIsVisiblePath = _bindingIsVisiblePath.GetValueFromBag(bag, context);             }         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>BindableImage.Bindings.g.cs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">\/\/ &lt;auto-generated\/> #pragma warning disable #nullable enable  ...  namespace BindableUIElements {     partial class BindableImage : IBindableElement     {         [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] private PropertyBindingData? _imageBindingData;  [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] private PropertyBindingData? _isVisibleBindingData;          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         [ExcludeFromCodeCoverage]         public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)         {             BeforeSetBindingContext(context, objectProvider);                          if (string.IsNullOrWhiteSpace(BindingImagePath) == false) { _imageBindingData ??= StringExtensions.ToPropertyBindingData(BindingImagePath!); _imageProperty = objectProvider.RentReadOnlyProperty&lt;Texture2D>(context, _imageBindingData!); _imageProperty!.ValueChanged += OnImagePropertyValueChanged; }  if (string.IsNullOrWhiteSpace(BindingIsVisiblePath) == false) { _isVisibleBindingData ??= StringExtensions.ToPropertyBindingData(BindingIsVisiblePath!); _isVisibleProperty = objectProvider.RentReadOnlyProperty&lt;bool>(context, _isVisibleBindingData!); _isVisibleProperty!.ValueChanged += OnIsVisiblePropertyValueChanged; }                  AfterSetBindingContext(context, objectProvider);         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         [ExcludeFromCodeCoverage]         public void ResetBindingContext(IObjectProvider objectProvider)         {             BeforeResetBindingContext(objectProvider);              if (_imageProperty != null) { _imageProperty!.ValueChanged -= OnImagePropertyValueChanged; objectProvider.ReturnReadOnlyProperty(_imageProperty); _imageProperty = null; }  if (_isVisibleProperty != null) { _isVisibleProperty!.ValueChanged -= OnIsVisiblePropertyValueChanged; objectProvider.ReturnReadOnlyProperty(_isVisibleProperty); _isVisibleProperty = null; }                          AfterResetBindingContext(objectProvider);         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private void OnImagePropertyValueChanged(object sender, Texture2D value) { OnImagePropertyValueChanged(value); }  [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private void OnIsVisiblePropertyValueChanged(object sender, bool value) { OnIsVisiblePropertyValueChanged(value); }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void BeforeSetBindingContext(IBindingContext context, IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void AfterSetBindingContext(IBindingContext context, IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void BeforeResetBindingContext(IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void AfterResetBindingContext(IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] partial void OnImagePropertyValueChanged(Texture2D value);  [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] partial void OnIsVisiblePropertyValueChanged(bool value);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0441\u0442\u0438\u043b\u0435\u0439 <code>image-info-view.uss<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<pre><code class=\"css\">...  .image--animation {     transition-property: translate;     transition-duration: 1250ms;     transition-timing-function: ease-out-cubic; }  .image--init-position {     translate: 0 256px; }<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>ImageInfoView.uxml<\/code> \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<pre><code class=\"cs\">public partial class ImageInfoViewModel : IImageInfoModel, IBindingContext {     private readonly Texture2D _invalidTexture = Texture2D.grayTexture;      [WithObservableBackingField]     public string Id     {         get => _id.Value;         set => _id.Value = value;     }      [WithObservableBackingField]     public string Author     {         get => _author.Value;         set => _author.Value = value;     }      [WithObservableBackingField]     public bool IsVisible     {         get => _isVisible.Value;         set => _isVisible.Value = value;     }      [WithObservableBackingField]     public Texture2D Image     {         get => _image.Value;         set         {             if (_image.Value != _invalidTexture)             {                 Object.Destroy(_image.Value);             }              _image.Value = value;         }     }      public void ResetWithId(string imageId)     {         Id = imageId;         Author = default;         IsVisible = default;          ReleaseImage();     }      public void SetInvalidState(string message)     {         Author = message;         Image = _invalidTexture;         IsVisible = true;     }      public void Dispose()     {         ReleaseImage();     }      private void ReleaseImage()     {         Image = null;     } }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0442\u0442\u0435\u0440 \u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>Image<\/code>. \u0414\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0443\u0442\u0435\u0447\u043a\u0438 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 \u0441\u0435\u0442\u0438 \u043d\u0435\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441.<\/p>\n<h2>Images Item<\/h2>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043f\u0438\u0441\u043a\u0430 <code>ImagesItemView.uxml<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u0432\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"xml\">&lt;ui:UXML ...>     &lt;ui:Template name=\"ImageInfoView\" src=\"...\" \/>     &lt;ui:VisualElement name=\"ImagesContainer\" usage-hints=\"GroupTransform\" class=\"image-item\">         &lt;ImageInfoBindingContextProvider binding-context-path=\"LeftImageInfo\" class=\"image-item__image-container\">             &lt;ui:Instance template=\"ImageInfoView\" name=\"LeftImageInfoContainer\" \/>         &lt;\/ImageInfoBindingContextProvider>         &lt;ImageInfoBindingContextProvider binding-context-path=\"RightImageInfo\" class=\"image-item__image-container\">             &lt;ui:Instance template=\"ImageInfoView\" name=\"RightImageInfoContainer\" \/>         &lt;\/ImageInfoBindingContextProvider>     &lt;\/ui:VisualElement> &lt;\/ui:UXML><\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0441\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 <code>ImageInfoBindingContextProvider<\/code>. \u0418\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0435\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u2013 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 <code>BindingContext<\/code> \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u0442\u043d\u043e\u0432. \u0422.\u0435. \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430 <code>LeftImageInfoContainer<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>BindingContext'\u0430<\/code> \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>LeftImageInfo<\/code>, \u0430 \u0434\u043b\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430 <code>RightImageInfoContainer<\/code> \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>RightImageInfo<\/code>.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>ImageInfoBindingContextProvider<\/code>:<\/p>\n<pre><code class=\"cs\">[UxmlElement] public partial class ImageInfoBindingContextProvider : BindingContextProvider&lt;ImageInfoViewModel> { }<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BindingContextProvider<\/code> \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439, \u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e <code>PropertyCastWrapper'\u043e\u0432<\/code>, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0443 \u043d\u0430\u0441 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435. \u0414\u0430, \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c UnityMvvmToolkit \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0443\u043b\u044b, \u0438 \u044d\u0442\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438\u0441\u044c \u0431\u044b \u0435\u0434\u0438\u043d\u043e\u0436\u0434\u044b \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c. \u041d\u043e \u0437\u0430\u0447\u0435\u043c \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c?<\/p>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>ImagesItemView.uxml<\/code> \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<pre><code class=\"cs\">public class ImagesItemViewModel : ICollectionItem, IDisposable {     private readonly IImagesItemModel _model;      ...      public ImagesItemViewModel(int id, IImagesItemModel model)     {         ...          LeftImageInfo = new ReadOnlyProperty((ImageInfoViewModel) model.LeftImageInfo);         RightImageInfo = new ReadOnlyProperty((ImageInfoViewModel) model.RightImageInfo);     }      public IReadOnlyProperty&lt;ImageInfoViewModel> LeftImageInfo { get; }     public IReadOnlyProperty&lt;ImageInfoViewModel> RightImageInfo { get; }      public void StartImagesLoading(int itemIndex)     {         if (TryUpdateItemIndex(itemIndex))         {             StopPreviousImagesLoading();              if (_isLoading == false)             {                 StartImagesLoadingAsync(itemIndex).Forget();             }         }     }      private bool TryUpdateItemIndex(int itemIndex)     {         if (_itemIndex == itemIndex)         {             return false;         }          _itemIndex = itemIndex;         return true;     }      private void StopPreviousImagesLoading()     {         _cancellationTokenSource?.Cancel();     }      private async UniTaskVoid StartImagesLoadingAsync(int itemIndex)     {         _isLoading = true;          while (_isLoading)         {             _cancellationTokenSource = new CancellationTokenSource();              try             {                 await _model                     .Configure(itemIndex)                     .LoadImagesAsync(_cancellationTokenSource.Token)                     .SuppressCancellationThrow();                  if (IsItemIndexValid(itemIndex, out var newItemIndex))                 {                     _isLoading = false;                 }                 else                 {                     itemIndex = newItemIndex;                 }             }             finally             {                 _cancellationTokenSource?.Dispose();                 _cancellationTokenSource = null;             }         }     }      private bool IsItemIndexValid(int itemIndex, out int newItemIndex)     {         newItemIndex = _itemIndex;         return itemIndex == _itemIndex &amp;&amp; _isDisposed == false;     } }<\/code><\/pre>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0443\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f. \u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <code>StartImagesLoading<\/code> \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f \u043b\u0438 \u0438\u043d\u0434\u0435\u043a\u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435. \u041f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e. \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u043e\u0432\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043c\u044b \u0434\u0435\u0440\u0436\u0438\u043c \u0435\u0451 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0439 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0438\u043d\u0434\u0435\u043a\u0441 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0451\u0442 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f <code>Dispose<\/code> \u0443 \u043a\u043b\u0430\u0441\u0441\u0430. \u0422.\u0435. \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 5 \u0438 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0443 \u043d\u0430\u0441 \u0438\u043d\u0434\u0435\u043a\u0441 \u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043e\u0441\u0442\u0430\u043b\u0441\u044f 5, \u0442\u043e \u043c\u044b \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 <code>while<\/code>, \u0438\u043d\u0430\u0447\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0435\u0441\u043b\u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, <code>_isDisposed == false<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>ImagesItemModel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">public class ImagesItemModel : IImagesItemModel {     ...      public IImageInfoModel LeftImageInfo { get; private set; }     public IImageInfoModel RightImageInfo { get; private set; }      public IImagesItemModel Configure(int itemIndex)     {         var imagesId = _imagesIdProvider.GetImagesId(itemIndex);          LeftImageInfo.ResetWithId(imagesId.LeftImageId);         RightImageInfo.ResetWithId(imagesId.RightImageId);                  return this;     }      public async UniTask LoadImagesAsync(CancellationToken cancellationToken)     {         await UniTask.WhenAll(             PopulateImageInfoAsync(LeftImageInfo, cancellationToken),             PopulateImageInfoAsync(RightImageInfo, cancellationToken));     }      private async UniTask PopulateImageInfoAsync(IImageInfoModel imageInfo, CancellationToken cancellationToken)     {         var result = await _imageDataProvider.DownloadImageInfoAsync(imageInfo.Id, cancellationToken);          if (result.IsFailure)         {             imageInfo.SetInvalidState(result.Error);             return;         }          JsonConvert.PopulateObject(result.Value.InfoJson, imageInfo);          imageInfo.Image = result.Value.Image;         imageInfo.IsVisible = true;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>ImageDataProvider<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">public sealed class ImageDataProvider : IImageDataProvider, IDisposable {     ...      public async UniTask&lt;Result&lt;(string InfoJson, Texture2D Image)>> DownloadImageInfoAsync(string imageId,         CancellationToken cancellationToken = default)     {         try         {             var urls = GetImageUrls(imageId);              var infoJson = await DownloadInfoAsync(urls.InfoUrl, cancellationToken);             if (infoJson is null)             {                 return Result.Failure&lt;(string, Texture2D)>(ImageInfoNotFound);             }              var image = await DownloadImageAsync(urls.ImageUrl, cancellationToken);              return image                 ? Result.Success&lt;(string, Texture2D)>((infoJson, image))                 : Result.Failure&lt;(string, Texture2D)>(ImageNotFound);         }         catch (UnityWebRequestException exception)         {             return Result.Failure&lt;(string, Texture2D)>(exception.ResponseCode == 404                 ? ImageNotFound                 : exception.Message);         }     }      private static async UniTask&lt;string> DownloadInfoAsync(string infoUrl, CancellationToken cancellationToken)     {         using var unityWebRequest = UnityWebRequest.Get(infoUrl);          await unityWebRequest             .SendWebRequest()             .WithCancellation(cancellationToken);          return unityWebRequest.result == UnityWebRequest.Result.Success             ? Encoding.UTF8.GetString(unityWebRequest.downloadHandler.data)             : null;     }      private static async UniTask&lt;Texture2D> DownloadImageAsync(string imageUrl, CancellationToken cancellationToken)     {         using var unityWebRequest = UnityWebRequestTexture.GetTexture(imageUrl);          await unityWebRequest             .SendWebRequest()             .WithCancellation(cancellationToken);          return unityWebRequest.result == UnityWebRequest.Result.Success             ? DownloadHandlerTexture.GetContent(unityWebRequest)             : null;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>Images Viewer<\/h2>\n<p>\u041d\u0443 \u0438, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f <code>ImagesViewerViewModel<\/code>.<\/p>\n<pre><code class=\"cs\">public class ImagesViewerViewModel : IBindingContext, IDisposable {     private const int MinItemsThreshold = 5;     private const int VirtualItemsIncrement = 5;      public ImagesViewerViewModel(IImagesViewerModel model)     {         if (model.ImagesItems.Count &lt; MinItemsThreshold)         {             throw new InvalidOperationException(                 $\"The number of reusable elements cannot be less than {MinItemsThreshold}.\");         }          var reusableImageItems =             new ReusableItemsList&lt;ImagesItemViewModel>(GetImagesItemViewModels(model.ImagesItems));          ImageItems = new ReadOnlyProperty&lt;ReusableItemsList&lt;ImagesItemViewModel>>(reusableImageItems);          MaxBindIndex = new Property&lt;int>();         MaxBindIndex.ValueChanged += OnMaxBindIndexChanged;     }      public IProperty&lt;int> MaxBindIndex { get; }     public IReadOnlyProperty&lt;ReusableItemsList&lt;ImagesItemViewModel>> ImageItems { get; }      public void Dispose()     {         foreach (var imagesItemViewModel in ImageItems.Value)         {             imagesItemViewModel.Dispose();         }          ImageItems.Value.Clear();         MaxBindIndex.ValueChanged -= OnMaxBindIndexChanged;     }      private void OnMaxBindIndexChanged(object sender, int maxIndex)     {         if (maxIndex == ImageItems.Value.Count - 1)         {             ImageItems.Value.AddVirtualItems(VirtualItemsIncrement);         }     }      private static IEnumerable&lt;ImagesItemViewModel> GetImagesItemViewModels(         IReadOnlyList&lt;IImagesItemModel> imagesItems)     {         for (var i = 0; i &lt; imagesItems.Count; i++)         {             yield return new ImagesItemViewModel(i, imagesItems[i]);         }     } }<\/code><\/pre>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>OnMaxBindIndexChanged<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0438\u0441\u0442\u0430\u043b \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0449\u0451 5 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e.<\/p>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c <code>ImagesViewerModel<\/code>:<\/p>\n<pre><code class=\"cs\">public sealed class ImagesViewerModel : IImagesViewerModel, IDisposable {     private const int InMemoryCacheItemsCount = 5;      ...      public IReadOnlyList&lt;IImagesItemModel> ImagesItems => _imagesItems;      private void CreateImagesItems(IImagesIdProvider imagesIdProvider, IImageDataProvider imageDataProvider)     {         _imagesItems = new IImagesItemModel[InMemoryCacheItemsCount];          for (var i = 0; i &lt; InMemoryCacheItemsCount; i++)         {             _imagesItems[i] = new ImagesItemModel(imagesIdProvider, imageDataProvider);         }     } }<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 <code>InMemoryCacheItemsCount<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0435 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e 5 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0443 \u043d\u0430\u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e 10 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u043e 2 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043f\u0438\u0441\u043a\u0430.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <code>ImagesViewerView.cs<\/code> \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 <code>DocumentView&lt;ImagesViewerViewModel><\/code>, \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c <code>ImagesItemView.uxml<\/code> \u0432 \u043f\u043e\u043b\u0435 <code>_imagesItemTemplate<\/code>, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 <code>ImagesItemViewModel<\/code>.<\/p>\n<pre><code class=\"cs\">public class ImagesViewerView : DocumentView&lt;ImagesViewerViewModel> {     [SerializeField] private VisualTreeAsset _imagesItemTemplate;      ...      protected override IReadOnlyDictionary&lt;Type, object> GetCollectionItemTemplates()     {         return new Dictionary&lt;Type, object>         {             { typeof(ImagesItemViewModel), _imagesItemTemplate }         };     } }<\/code><\/pre>\n<p><code>DocumentView&lt;TBindingContext><\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 <code>View<\/code> \u0438 <code>ViewModel<\/code>.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0448\u0443 View <code>ImagesViewerView.uxml<\/code> \u0438 \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0443 <code>BindableImageListView<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>binding-items-source-path<\/code> \u0443\u043a\u0430\u0437\u0430\u0442\u044c <code>ImageItems<\/code>.<\/p>\n<pre><code class=\"xml\">&lt;ui:UXML xmlns:uitk=\"UnityMvvmToolkit.UITK.BindableUIElements\" ...>     &lt;Style src=\"project:\/\/database\/Assets\/UI%20Toolkit\/Styles\/root.uss?fileID=7433441132597879392&amp;amp;guid=e3fa7fbf0e9b3fb48916d2e77209f1ca&amp;amp;type=3#root\" \/>     &lt;Style src=\"project:\/\/database\/Assets\/UI%20Toolkit\/Styles\/main-view.uss?fileID=7433441132597879392&amp;amp;guid=0532dc2e51322554a9b731042cfb65ae&amp;amp;type=3#main-view\" \/>     &lt;SafeAreaContainer usage-hints=\"GroupTransform\">         &lt;ui:VisualElement name=\"Header\" usage-hints=\"GroupTransform\" class=\"main-view__header\">             &lt;uitk:BindableLabel text=\"Images\" class=\"main-view__header-label main-view__header-label--left\" \/>             &lt;uitk:BindableLabel text=\" Viewer\" class=\"main-view__header-label main-view__header-label--right\" \/>         &lt;\/ui:VisualElement>         &lt;ui:VisualElement name=\"Content\" usage-hints=\"GroupTransform\" class=\"main-view__content\">             &lt;BindableImageListView name=\"ImagesListView\" binding-items-source-path=\"ImageItems\" \/>         &lt;\/ui:VisualElement>     &lt;\/SafeAreaContainer> &lt;\/ui:UXML><\/code><\/pre>\n<blockquote>\n<p>P.S. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u044f\u0432\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c <code>MaxBindIndex<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>binding-max-bind-index-path<\/code> \u0443 \u043d\u0430\u0448\u0435\u0433\u043e <code>BindableImageListView<\/code>. \u0412\u0441\u0451 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441\u0440\u0430\u0437\u0443 \u0432 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>_maxBindIndexProperty<\/code> \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0435\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 <code>ViewModel<\/code>.<\/p>\n<\/blockquote>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e \u0434\u043b\u044f Android \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/drive.google.com\/file\/d\/1bee9PudBmniugH9IZN6ttKLuQ0aIGday\/view?usp=sharing\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>, \u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c \u0438 \u043a UnityMvvmToolkit.Generator \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <a href=\"https:\/\/boosty.to\/dimachebanov\/posts\/1ebd791b-3926-4f1a-82c2-b31cdcd046aa?share=post_link\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u0410 \u043a\u0430\u043a\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0412\u044b \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \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? MVC, MVP, \u0438\u043b\u0438 MVVM?<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/articles\/746782\/\"> https:\/\/habr.com\/ru\/articles\/746782\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 ListView c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/64a9671c53324501d3e965f4\" data-style=\"\" id=\"64a9671c53324501d3e965f4\" width=\"\"><\/div>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/unity.com\/features\/ui-toolkit\" rel=\"noopener noreferrer nofollow\">Unity UI Toolkit<\/a> \u0432 \u043f\u0430\u0440\u0435 \u0441 <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit\" rel=\"noopener noreferrer nofollow\">UnityMvvmToolkit<\/a>. \u042f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b \u043f\u0440\u043e UnityMvvmToolkit \u0441\u0442\u0430\u0442\u044c\u044e \u0432\u043e\u0442 <a href=\"https:\/\/habr.com\/ru\/articles\/689134\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u0421 \u0442\u0435\u0445 \u043f\u043e\u0440 API \u043f\u0440\u0438\u0442\u0435\u0440\u043f\u0435\u043b \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435, \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043f\u043b\u044e\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0434\u0430\u0439\u0442\u0435 \u0437\u043d\u0430\u0442\u044c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u043d\u0430\u043f\u0438\u0448\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043f\u043e \u043d\u0435\u0439.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0441\u043f\u0438\u0441\u043e\u043a \u0443 \u043d\u0430\u0441 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439, \u043c\u044b \u043f\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u0422\u0430\u043a\u0436\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0445\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0421\u043f\u0438\u0441\u043e\u043a \u0443 \u043d\u0430\u0441 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439, \u0430 \u0432\u043e\u0442 \u043f\u0430\u043c\u044f\u0442\u044c, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435\u0442.<\/p>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 ListView \u0432 Unity UI Toolkit \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0447\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043d\u0430\u043c \u0440\u0430\u0431\u043e\u0442\u0443. \u041e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435.<\/p>\n<blockquote>\n<p>P.S. \u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u043d\u0438\u0436\u0435 \u043a\u043e\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 <a href=\"https:\/\/github.com\/LibraStack\/UnityUxmlGenerator\" rel=\"noopener noreferrer nofollow\">UnityUxmlGenerator<\/a> \u0438 <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit#source-code-generator\" rel=\"noopener noreferrer nofollow\">UnityMvvmToolkit.Generator<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u0431\u0430\u0432\u044f\u0442 \u043d\u0430\u0441 \u043e\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u0443\u0447\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d.<\/p>\n<\/blockquote>\n<blockquote>\n<p>P.P.S. \u0414\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit#unitymvvmtoolkit\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439<\/a> UnityMvvmToolkit. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b <a href=\"https:\/\/github.com\/LibraStack\/UnityMvvmToolkit#watch-quick-start\" rel=\"noopener noreferrer nofollow\">Quick start<\/a>.<\/p>\n<\/blockquote>\n<h2>Reusable Items List<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f <code>ReusableItemsList<\/code>. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u043d\u0451\u043c. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0443\u0442: <code>IList&lt;T><\/code>, <code>IList<\/code>, <code>INotifyCollectionChanged<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>IList<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c <code>ReusableItemsList<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>itemsSource<\/code> \u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e <code>ListView<\/code>, \u0430 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0434\u0432\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 <code>BindableListView<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 UnityMvvmToolkit.<\/p>\n<pre><code class=\"cs\">public class ReusableItemsList&lt;T> : List&lt;T>, IList&lt;T>, IList, INotifyCollectionChanged {     private int _virtualCount;      public ReusableItemsList(IEnumerable&lt;T> items) : base(items)     {     }      public new T this[int index]     {         get         {             var itemsCount = base.Count;              return itemsCount == 0 ? default : base[index % itemsCount];         }     }      object IList.this[int index]     {         get => this[index];         set => throw new NotImplementedException();     }      public new int Count => base.Count + _virtualCount;      public event NotifyCollectionChangedEventHandler CollectionChanged;      public void AddVirtualItems(int count)     {         _virtualCount += count;         CollectionChanged?.Invoke(this, default);     } }<\/code><\/pre>\n<p>\u041f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u043d\u043e \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435 \u2013 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 <code>base[index % itemsCount]<\/code>. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 10 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 20, \u0442\u043e \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 10 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442 0, \u0430 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 15 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442 5. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u0442\u043e \u043f\u043e\u0434\u0432\u043e\u0445 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u0435\u043d. \u041d\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u0437\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u044b \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u2013 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 <code>base.Count + _virtualCount<\/code>. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445. \u042d\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>ListView<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043e\u0441\u044b \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u0435\u0442\u043e\u0434 <code>AddVirtualItems<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0438 <code>CollectionChanged<\/code> \u0443 \u043d\u0430\u0441 <code>NotifyCollectionChangedEventArgs<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>default<\/code>. \u042d\u0442\u043e \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<h2>Images ListView<\/h2>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BindableImageListView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0411\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>BindableListView&lt;TItemBindingContext, TCollection><\/code>, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0443\u043a\u0430\u0436\u0435\u043c <code>ReusableItemsList<\/code> \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0430\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<pre><code class=\"cs\">[BindableElement] public partial class BindableImageListView :     BindableListView&lt;ImagesItemViewModel, ReusableItemsList&lt;ImagesItemViewModel>> {     [BindableProperty(defaultValue: \"MaxBindIndex\")]     private IProperty&lt;int> _maxBindIndexProperty;      protected override void BindItem(VisualElement item, int index, ImagesItemViewModel imagesItem,         IObjectProvider objectProvider)     {         if (_maxBindIndexProperty.Value &lt; index)         {             _maxBindIndexProperty.Value = index;         }          imagesItem.StartImagesLoading(index);         base.BindItem(item, index, imagesItem, objectProvider);     }      protected override void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)     {     } }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <code>BindItem<\/code>. \u0418\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u2013 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f <code>_maxBindIndexProperty<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u041d\u0443 \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>StartImagesLoading<\/code> \u0443 \u043d\u0430\u0448\u0435\u0439 <code>ViewModel'\u0438<\/code> \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 <code>NotifyCollectionChangedEventArgs<\/code> \u0431\u0443\u0434\u0435\u0442 <code>null<\/code>, \u043d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>OnItemsCollectionChanged<\/code>. \u0415\u0433\u043e \u043c\u043e\u0436\u0435\u043c \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>VirtualizationController<\/code> \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>OnScroll<\/code> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u043e\u0441\u0443 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438.<\/p>\n<blockquote>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b <code>BindableElement<\/code> \u0438 <code>BindableProperty<\/code> \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<\/blockquote>\n<details class=\"spoiler\">\n<summary>BindableImageListView.Uxml.g.cs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">\/\/ &lt;auto-generated\/> #pragma warning disable #nullable enable  ...  namespace BindableUIElements {     partial class BindableImageListView     {         [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private string BindingMaxBindIndexPath { get; set; }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         public new class UxmlFactory : UxmlFactory&lt;BindableImageListView, UxmlTraits>         {         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         public new class UxmlTraits : BindableListView&lt;ImagesItemViewModel, ReusableItemsList&lt;ImagesItemViewModel>>.UxmlTraits         {             [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             private readonly UxmlStringAttributeDescription _bindingMaxBindIndexPath = new()                  { name = \"binding-max-bind-index-path\", defaultValue = \"MaxBindIndex\" };              [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]             [ExcludeFromCodeCoverage]             public override void Init(VisualElement visualElement, IUxmlAttributes bag, CreationContext context)             {                 base.Init(visualElement, bag, context);                  var control = (BindableImageListView) visualElement;                 control.BindingMaxBindIndexPath = _bindingMaxBindIndexPath.GetValueFromBag(bag, context);             }         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>BindableImageListView.Bindings.g.cs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">\/\/ &lt;auto-generated\/> #pragma warning disable #nullable enable  ...  namespace BindableUIElements {     partial class BindableImageListView : IBindableElement     {         [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] private PropertyBindingData? _maxBindIndexBindingData;          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         [ExcludeFromCodeCoverage]         public override void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)         {             BeforeSetBindingContext(context, objectProvider);              base.SetBindingContext(context, objectProvider);              if (string.IsNullOrWhiteSpace(BindingMaxBindIndexPath) == false) { _maxBindIndexBindingData ??= StringExtensions.ToPropertyBindingData(BindingMaxBindIndexPath!); _maxBindIndexProperty = objectProvider.RentProperty&lt;int>(context, _maxBindIndexBindingData!); _maxBindIndexProperty!.ValueChanged += OnMaxBindIndexPropertyValueChanged; }                  AfterSetBindingContext(context, objectProvider);         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         [ExcludeFromCodeCoverage]         public override void ResetBindingContext(IObjectProvider objectProvider)         {             BeforeResetBindingContext(objectProvider);              if (_maxBindIndexProperty != null) { _maxBindIndexProperty!.ValueChanged -= OnMaxBindIndexPropertyValueChanged; objectProvider.ReturnProperty(_maxBindIndexProperty); _maxBindIndexProperty = null; }              base.ResetBindingContext(objectProvider);              AfterResetBindingContext(objectProvider);         }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] [ExcludeFromCodeCoverage] private void OnMaxBindIndexPropertyValueChanged(object sender, int value) { OnMaxBindIndexPropertyValueChanged(value); }          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void BeforeSetBindingContext(IBindingContext context, IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void AfterSetBindingContext(IBindingContext context, IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void BeforeResetBindingContext(IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")]         partial void AfterResetBindingContext(IObjectProvider objectProvider);          [GeneratedCodeAttribute(\"UnityMvvmToolkit.Generator\", \"1.0.0.0\")] partial void OnMaxBindIndexPropertyValueChanged(int value);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>Image Info<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d <code>ImageInfoView.uxml<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 <code>ImagesItemView.uxml<\/code>.<\/p>\n<pre><code class=\"xml\">&lt;ui:UXML xmlns:uitk=\"UnityMvvmToolkit.UITK.BindableUIElements\" ...>     &lt;ui:VisualElement<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-405202","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/405202","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=405202"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/405202\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=405202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=405202"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=405202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}