MessageDialog for IoT using Caliburn micro

Hi all, we have seen in the past artcle how to make working Caliburn micro in our UWP application. In the last article we’ve found the messagedialog with a standard UWP and now I’m going to show how to make a MessageDialog for IoT (Raspberry Pi2) using Caliburn micro in the main application.

First of all

I use to manage all the user controls with it’s own code behind and not with the ViewModel. In this case I’ll make a user control for my personal MessageDialog for IoT.

Ok, let’s start with a UWP blank project and download from Nuget Caliburn Micto (actually at v.2.0.2) and go to configure the bootstrapper in the App.Xaml.

Now I’ve found another issue: Caliburn now is not resolving automatically the Windows.Xaml.Interactivity dependence. But the question is: where is it? Simply, must add the reference to ‘Behaviors SDK (XAML)’ from references. I know, is not so clear, but in any case, so much so and I’ve fixed and reported here “Ad futuram rei memoriam” because I’ve no memory myself 😀

The reference is it:

Blend SDK

And now we can go ahead.

In the preview article, we have found an exception of System.Runtime.InteropService.COMException when we tried to notify the property change from our dialog.

Now we have added references to Caliburn, we have added a ViewModel linked to the corresponding view. But this link is not real, is made from Caliburn and when we tried to notify the property we could have the same exception. I sayd “could” because if we have the same thread and the same context, the application could still work.

In any case what is better to do is pass the current view for take the dispatcher.

Our method ShowDialog will be trasformad as this:

[code lang=”csharp” title=”+ Show Dialog method”]private object AttachedView = null; 
public async Task<DialogResult> ShowDialog<T>(string title, string subtitle, string tit, object view) 

    AttachedView = Convert.ChangeType(view, typeof(T)); 
    TextTitle = title; 
    SubTitle = subtitle; 
    Title = tit; 
    IsShown = true; 
    return await Task.Run(() => { SpinWait.SpinUntil(() => !IsShown); return result; }); 
}[/code]

This is a generic method that will receive the reference at our view like object and after we will cast properly and stored to a variable for next use in our OnNotifyPropertyChanged method that will be modifies as:

[code title=”+ Implementation of INotifyPropertyChanged” language=”csharp”]private void OnNotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
if (AttachedView == null)
return;
Task.Run(async () =>
{
await ((Page)AttachedView).Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
handler(this, new PropertyChangedEventArgs(name));
});
});
}
}
}[/code]

Take not the cast at the line

[code title=”+ Attached view” language=”csharp”]await ((Page)AttachedView).Dispatcher.RunAsync(…[/code]

the (Page) is because we will not know before what of our views will be implemented, and we stay over.

In that manner the application will continue running.

At the end we will manage our result of the box. If we implement a switch to manage the cases, we will found another exception like the one before. What we have to do is reported here:

[code lang=”csharp” title=”+ Caliburn GetView()”]var v = GetView() as MainPageView;
switch (dialogResult)
{
case Dialog.DialogResult.Yes:
await Task.Run(async () =>
{
await (v.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
v.textBlockResult.Text = "The result is ‘Yes’";
}));
});
break;
….[/code]

we have to pass trough the reference of the view. Take note the CoreDispatcherPriority setted to low: this is for do not load too mutch for update a textblock.

The last step of our test project is to make possible use the system MessageDialog when the application is targetted to desktop or tablet or phone. We have to check the platform. The unique platform where we would use our MessageDialog is the IoT and we have to check it. The code is this:

[code lang=”csharp” title=”+ Verify the device family”]string platform = AnalyticsInfo.VersionInfo.DeviceFamily;
IUICommand res = new UICommand();
if (platform != "Windows.IoT")
{
var dialog = new Windows.UI.Popups.MessageDialog("consectetur adipiscing elit. Sed interdum, augue at ultrices dictum, " +
"lectus nisi cursus est, at vestibulum sapien arcu in justo. In mattis " +
"rhoncus diam at aliquam. Praesent eros dolor, scelerisque eu turpis lobortis, " +
"dignissim aliquam erat. Aenean id eros in sem euismod fermentum a eu elit. Ut " +
"congue elit a risus aliquam placerat. Ut vel iaculis ante. In sodales porta orci " +
"a venenatis.");
dialog.Title = "Lorem ipsum dolor sit amet";
dialog.Commands.Add(new UICommand { Label = "Yes", Id = 0 });
dialog.Commands.Add(new UICommand { Label = "No", Id = 1 });
dialog.Commands.Add(new UICommand { Label = "Cancel", Id = 2 } );
res = await dialog.ShowAsync();
switch ((int)res.Id)
{
case 0:
v.textBlockResult.Text = "The result is ‘Yes’";
break;
case 1:
v.textBlockResult.Text = "The result is ‘No’";
break;
case 2:
v.textBlockResult.Text = "The result is ‘Cancel’";
break;
default:
v.textBlockResult.Text = "The result is ‘Unespected’";
break;
}
}[/code]

That’s all. I know that is not perfect, but it would only be a starting point. Here the complete project. MessageDialog.zip

Stay tuned!