{"id":1110,"date":"2011-03-27T16:00:36","date_gmt":"2011-03-27T15:00:36","guid":{"rendered":"http:\/\/www.minddriven.de\/?p=1110"},"modified":"2011-03-26T17:52:55","modified_gmt":"2011-03-26T16:52:55","slug":"wp7-xaml-viewmodel-busy-indicator","status":"publish","type":"post","link":"https:\/\/www.minddriven.de\/index.php\/technology\/dot-net\/windows-phone\/wp7-xaml-viewmodel-busy-indicator","title":{"rendered":"WP7 #4: A XAML\/VM-driven Busy Indicator"},"content":{"rendered":"<p>This blog post introduces a <strong>Busy Indicator control<\/strong> for Windows Phone 7, which can be driven\/defined by XAML and allows binding of the busy state via a ViewModel property. This control can be defined around arbitrary page elements and handles the visibility of the application bar, as well.<\/p>\n<h3>Introduction<\/h3>\n<p>Indicating the busy state is a common task of applications, that perform many actions asynchronously, while remaining responsive, like Silverlight and Windows Phone applications. It&#8217;s up to the developer to show the busy state in dependency of an operation and to disable parts of a page, which should not be selectable\/changeable in the meantime. For <strong>Windows Phone 7<\/strong> there are some solutions, but I was surprised that I couldn&#8217;t find a satisfying one for me. Either the level of control was inadequate (for example giving users the possibility to change\/select controls) or the busy indicator was set\/initialized directly from code (code behind\/ViewModel), which is more kind of an anti-pattern for me. Thus I decided to look at my favorite busy indicator control for (web-target) Silverlight and to port it to Windows Phone 7.<\/p>\n<div style=\"float: left;\">\n<figure id=\"attachment_1175\" aria-describedby=\"caption-attachment-1175\" style=\"width: 213px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1175\" title=\"Not Busy BusyIndicator\" src=\"http:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_NotBusy.png\" alt=\"BusIndicator Not Busy State\" width=\"213\" height=\"400\" srcset=\"https:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_NotBusy.png 213w, https:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_NotBusy-159x300.png 159w\" sizes=\"auto, (max-width: 213px) 100vw, 213px\" \/><figcaption id=\"caption-attachment-1175\" class=\"wp-caption-text\">Not Busy<\/figcaption><\/figure>\n<\/div>\n<div style=\"float: left;\">\n<figure id=\"attachment_1176\" aria-describedby=\"caption-attachment-1176\" style=\"width: 214px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1176\" title=\"Busy BusyIndicator\" src=\"http:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_IsBusy.png\" alt=\"BusyIndicator with Full Busy State\" width=\"214\" height=\"400\" srcset=\"https:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_IsBusy.png 214w, https:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_IsBusy-160x300.png 160w\" sizes=\"auto, (max-width: 214px) 100vw, 214px\" \/><figcaption id=\"caption-attachment-1176\" class=\"wp-caption-text\">Busy State on Whole Page<\/figcaption><\/figure>\n<\/div>\n<div style=\"float: left;\">\n<figure id=\"attachment_1177\" aria-describedby=\"caption-attachment-1177\" style=\"width: 213px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1177\" title=\"Partial Busy BusyIndicator\" src=\"http:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_IsBusy_Partial.png\" alt=\"BusyIndicator with Partial Busy State\" width=\"213\" height=\"400\" srcset=\"https:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_IsBusy_Partial.png 213w, https:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicator_IsBusy_Partial-159x300.png 159w\" sizes=\"auto, (max-width: 213px) 100vw, 213px\" \/><figcaption id=\"caption-attachment-1177\" class=\"wp-caption-text\">Partial Busy State<\/figcaption><\/figure>\n<\/div>\n<h3 style=\"clear: both;\">Structure and usage<\/h3>\n<p>My implementation of the busy indicator consists of 2 components: the <strong>BusyIndicatorControl<\/strong> as core part and the <strong>BusyIndicatorStyle<\/strong> in the <code>Styles.xaml<\/code> for the layout. The implementation uses the <code>PerformanceProgressBar<\/code> from the Silverlight for Windows Phone Toolkit (Feb2011 or newer), so make sure you&#8217;ve installed it.<\/p>\n<p>The usage of the <code>BusyIndicatorControl<\/code> is fairly simple. In your XAML just place the control around those controls, which you want to set to &#8222;busy&#8220;. Bind the <code>IsBusy<\/code> property to your ViewModel\/code behind property, set the <code>BusyText<\/code> and that&#8217;s it! Optionally, with <code>HideApplicationBar<\/code> you can indicate if you want to show or hide the application bar, when <code>IsBusy==true<\/code>.<\/p>\n<p>Here&#8217;s an example, showing the usage of the control in a simple scenario:<\/p>\n<pre class=\"brush:xml\">&lt;phone:PhoneApplicationPage\r\n    x:Class=\"BusyIndicatorControl.MainPage\"\r\n    xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\r\n    xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\r\n    xmlns:phone=\"clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone\"\r\n    xmlns:controls=\"clr-namespace:BusyIndicatorControl.Controls\"&gt;\r\n\r\n    &lt;controls:BusyIndicatorControl x:Name=\"busyIndicator\" Style=\"{StaticResource BusyIndicatorStyle}\"\r\n                                   BusyText=\"Doing something...\"\r\n\t\t\t           IsBusy=\"{Binding IsDoingSomething}\"\r\n                                   HideApplicationBar=\"True\"&gt;\r\n\r\n        &lt;Grid x:Name=\"LayoutRoot\" Background=\"Transparent\"&gt;\r\n            &lt;Grid.RowDefinitions&gt;\r\n                &lt;RowDefinition Height=\"Auto\"\/&gt;\r\n                &lt;RowDefinition Height=\"*\"\/&gt;\r\n            &lt;\/Grid.RowDefinitions&gt;\r\n\r\n            &lt;StackPanel x:Name=\"TitlePanel\" Grid.Row=\"0\" Margin=\"12,17,0,28\"&gt;\r\n                &lt;TextBlock x:Name=\"ApplicationTitle\" Text=\"Controls\" \r\n                           Style=\"{StaticResource PhoneTextNormalStyle}\"\/&gt;\r\n                &lt;TextBlock x:Name=\"PageTitle\" Text=\"Busy Indicator\" Margin=\"9,-7,0,0\" \r\n                           Style=\"{StaticResource PhoneTextTitle1Style}\"\/&gt;\r\n            &lt;\/StackPanel&gt;\r\n\r\n            &lt;Grid x:Name=\"ContentPanel\" Grid.Row=\"1\" Margin=\"12,0,12,0\"\r\n                  Height=\"550\" VerticalAlignment=\"Top\"&gt;\r\n                &lt;Button Content=\"Do Something\" Height=\"80\" Width=\"300\"\r\n                    Click=\"Button_Click\" \/&gt;\r\n            &lt;\/Grid&gt;\r\n        &lt;\/Grid&gt;\r\n    &lt;\/controls:BusyIndicatorControl&gt;\r\n\r\n    &lt;phone:PhoneApplicationPage.ApplicationBar&gt;\r\n        &lt;shell:ApplicationBar IsVisible=\"True\" IsMenuEnabled=\"True\"&gt;\r\n            &lt;shell:ApplicationBarIconButton IconUri=\"\/Assets\/Icons\/appbar.check.rest.png\" Text=\"Check\"\r\n                                            Click=\"ApplicationBarIconButton_Click\" \/&gt;\r\n            &lt;shell:ApplicationBarIconButton IconUri=\"\/Assets\/Icons\/appbar.close.rest.png\" Text=\"Close\"\/&gt;\r\n        &lt;\/shell:ApplicationBar&gt;\r\n    &lt;\/phone:PhoneApplicationPage.ApplicationBar&gt;\r\n\r\n&lt;\/phone:PhoneApplicationPage&gt;<\/pre>\n<p>In this case, the whole phone page would be set to &#8222;disabled&#8220; by the overlay of the busy indicator control and the application bar would hide, when the <code>IsBusy<\/code> property is set to <code>true<\/code>. <code>IsBusy<\/code> is bound to a property <code>IsDoingSomething<\/code> in the ViewModel, which controls the visibility and state of the busy indicator. Of course, you can choose the area to disable and change the property values and the style of the control as you want.<\/p>\n<h3>Features<\/h3>\n<p>This busy indicator includes the following main features:<\/p>\n<ul>\n<li>Definition on arbitrary parts\/controls of a phone page.<\/li>\n<li>Definition through XAML.<\/li>\n<li>Control through data binding, e.g. from ViewModel (busy state and text).<\/li>\n<li>Creates an overlay over controls, that should be updated.<\/li>\n<li>Option to hide the ApplicationBar, when the indicator is busy.<\/li>\n<\/ul>\n<h3>Sourcecode<\/h3>\n<p>Here&#8217;s a sample project, which includes the control and shows the usage of the busy indicator. <code>Controls\/BusyIndicatorControl.cs<\/code> and <code>Assets\/Styles.xaml<\/code> is what you need. Please make sure that you&#8217;ve installed the Silverlight for Windows Phone <a href=\"http:\/\/silverlight.codeplex.com\/releases\/view\/60291\" target=\"_blank\">Toolkit <\/a>with at least the version Feb2011. Feel free to change and redistribute the code at will&#8230;<\/p>\n<p>[<a href=\"http:\/\/www.minddriven.de\/wp-content\/uploads\/2011\/03\/BusyIndicatorControl.zip\">Sourcecode Download<\/a>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog post introduces a Busy Indicator control for Windows Phone 7, which can be driven\/defined by XAML and allows binding of the busy state via a ViewModel property. This control can be defined around arbitrary page elements and handles the visibility of the application bar, as well. Introduction Indicating the busy state is a &hellip; <a href=\"https:\/\/www.minddriven.de\/index.php\/technology\/dot-net\/windows-phone\/wp7-xaml-viewmodel-busy-indicator\" class=\"more-link\"><span class=\"screen-reader-text\">WP7 #4: A XAML\/VM-driven Busy Indicator<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[282],"tags":[295,296,283,284,285,76],"class_list":["post-1110","post","type-post","status-publish","format-standard","hentry","category-windows-phone","tag-busy-indicator","tag-viewmodel","tag-windows-phone-7","tag-wp7","tag-wp7dev","tag-xaml"],"_links":{"self":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/1110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/comments?post=1110"}],"version-history":[{"count":25,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/1110\/revisions"}],"predecessor-version":[{"id":1187,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/1110\/revisions\/1187"}],"wp:attachment":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/media?parent=1110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/categories?post=1110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/tags?post=1110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}