Post on 14-Jul-2015
Agenda Windows 8/Windows Phone
In this module, we
will....
Extension methods
Portable Class Libraries
MVVM Architecture
Data Binding Linked files
A common user experience
#if conditionals
In this module:
Common Structure
Model-View-ViewModel
View
ViewModel
Commands
Data Binding
Model
MVVM Benefits
• Reuse Model and View-Model code
• Test the ViewModel with unit tests
• Maintainability
• Can show design-time data in Expression Blend and the Visual Studio designer
Model – View - ViewModel
public class MyModelItem{
public int Id { get; set; }
[DataMember(Name = "text")]public string Text { get; set; }
[DataMember(Name = "complete")]public bool Complete { get; set; }
}
public class MyModelItem{
public int Id { get; set; }
[DataMember(Name = "text")]public string Text { get; set; }
[DataMember(Name = "complete")]public bool Complete { get; set; }
}
Data Service Calls in the ViewModel
private MobileServiceCollectionView<TodoItem> items;private IMobileServiceTable<TodoItem> todoTable = App.MobileService.GetTable<TodoItem>();
private void RefreshTodoItems(){
items = todoTable.Where(todoItem => todoItem.Complete == false).ToCollectionView();
}
private async void InsertTodoItem(TodoItem todoItem){
await todoTable.InsertAsync(todoItem);items.Add(todoItem);
}
Extract Model and Service Calls
Good MVVM Practice
2
DataBinding(INotifyPropertyChanged)
Data Binding in the ViewModel
// Create INotifyPropertyChanged property called VisibleItemsprivate void MobileServiceCollectionView<TodoItem> RefreshTodoItems(){
items = todoTable.Where(todoItem => todoItem.Complete == false).ToCollectionView();
_visibleItems.Clear();foreach (var item in items){
_visibleItems.Add(item);}NotifyPropertyChanged("VisibleItems");
}
Improved Structure
“Add as Link”
“Add as Link”
Common APIs in Windows 8 and Windows
Phone 8
Common APIs
Hardware Implementation: Accelerometer
Hardware Implementation: Accelerometer
<Canvas x:Name="hostCanvas" Loaded=“canvas_Loaded">
Accelerometer _accel;private void canvas_Loaded(object sender, RoutedEventArgs e){
_accel = Accelerometer.GetDefault();if (_accel != null)
_accel.ReadingChanged += _accel_ReadingChanged;}
Hardware Implementation: Accelerometer
void _accel_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args){
double _accelX = args.Reading.AccelerationX;double _accelY = args.Reading.AccelerationY;// Update the position of the ellipse
}
Threading Difference
Threading
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>{
double _accelX = args.Reading.AccelerationX;double _accelY = args.Reading.AccelerationY;// Update ellipse location
});
Deployment.Current.Dispatcher.BeginInvoke(() =>{
double _accelX = args.Reading.AccelerationX;double _accelY = args.Reading.AccelerationY;//Update ellipse location
});
#if Complier Conditionals
#if Conditional Blocks
#if NETFX_COREDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {#endif
#if WINDOWS_PHONEDeployment.Current.Dispatcher.BeginInvoke(() => {#endif
#if Conditional Blocks
Threading
#if NETFX_COREDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {#elseDeployment.Current.Dispatcher.BeginInvoke(() => {#endif
double _accelX = args.Reading.AccelerationX;double _accelY = args.Reading.AccelerationY;
Extension Methods
Web Service
HttpWebResponse and HttpWebRequest
var request = (HttpWebRequest)WebRequest.Create(autoCompleteUri);
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
// retrieve data using StreamReader
HttpWebResponse and HttpWebRequest
var request = (HttpWebRequest)WebRequest.Create(autoCompleteUri);request.BeginGetResponse(new AsyncCallback(AutoCompleteCallback), request);}
private void AutoCompleteCallback(IAsyncResult callback){
HttpWebRequest request = (HttpWebRequest)callback.AsyncState;HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callback);// retrieve data using StreamReader
}
Extension Methods
public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request){
var taskComplete = new TaskCompletionSource<HttpWebResponse>();request.BeginGetResponse(asyncResponse =>{
HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
taskComplete.TrySetResult(someResponse);}, request);
return taskComplete.Task;}
HttpWebResponse and HttpWebRequest
#if WINDOWS_PHONEusing MyExtensionClass#endif
var request = (HttpWebRequest)WebRequest.Create(autoCompleteUri);
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
// retrieve data using StreamReader
Translating User
Experience
Web Service
UI Differences and XAML
Different Form Factors Require Different UX
Different Form Factors Require Different UX
User Experience Considerations
One-handed touch most common
Guaranteed hardware, such as camera and accelerometer
Avoid multiple columns of content
Scroll vertically for more content
Very limited room on the app bar
Hardware back button
No semantic zoom
• Windows 8
One or two-handed touch, mouse
No guarantee of any specific hardware, must check at runtime
Rows and columns of content are normal
Scroll horizontally for more content
Significant room on the app bar
On-screen back button
Semantic zoom
Windows Phone 8
Design the UX separately for each platform!
• Avoid reusing XAML across Windows Phone 8 and Windows 8
• Major differences in the platforms make this difficult anyway:–XAML namespaces
–XAML controls
–User experience
–Screen space
–Page layout / orientation
XAML
• Windows.UI.Xaml.Controls contains Windows 8 controls• Microsoft.Phone.Controls and Microsoft.Phone.Shell contain WP8
controls• System.Windows.Controls contains Windows 8 controls and some shared
controls• Some controls are present on both platforms but in different namespaces
• Example: Windows.UI.Xaml.Controls.Canvas (Win8), System.Windows.Controls.Canvas (WP8)
XAML Namespaces and Controls
Different Controls
Different Controls
Different Controls
Different Form Factors Require Different UX
Different Form Factors Require Different UX
Different Form Factors Require Different UX
Translating UX
Translating UX – Details View
Different Form Factors Require Different UX
• Tiles are an entry point for Windows 8 and Windows Phone 8 apps–One primary tile that launches
the app normally–Also, secondary tiles can be
pinned to the Start screen• Create a “Deep link” that takes
the user to a specific page in the app
• Both platforms support live tiles, in which content is periodically updated
Tiles
Tiles on Windows 8 Tiles on Windows Phone 8
var tile = new SecondaryTile(item.UniqueId, // Tile IDitem.ShortTitle, // Tile short nameitem.Title, // Tile display nameitem.UniqueId, // Activation argumentTileOptions.ShowNameOnLogo, // Tile optionsuri // Tile logo URI
);
await tile.RequestCreateAsync();
CycleTileData tileData = new CycleTileData()
{
Title = group.Title,
SmallBackgroundImage = new
Uri(group.GetImageUri(),
UriKind.RelativeOrAbsolute),
CycleImages = list
};
ShellTile.Create(new Uri(navDataSource,
UriKind.Relative), tileData, true);
Both platforms support tiles, but the APIs are completely different
Tiles (cont.)
Windows 8 TilesWindows Phone 8 Tiles
• With webcams and cell phones, capturing photos and videos is prolific–Both Windows 8 and Windows Phone 8
have media capture APIs
Media Capture
Windows Phone 8 camera app
Windows 8 camera app
Media Capture (Windows 8)• Windows uses CameraCaptureUI to capture images and videos
• Windows.Media.Capture namespace
• Enable Webcam and Microphone in the manifest
private async void OnCapturePhoto(object sender, TappedRoutedEventArgs e)
{
var camera = new CameraCaptureUI();
var file = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (file != null)
{
// Do something with the result...
}
}
Media Capture (Windows Phone 8)Windows Phone uses CameraCaptureTask take photos
Microsoft.Phone.Tasks namespace
Enable ID_CAP_ISV_CAMERA and ID_CAP_MICROPHONE in the manifest
Recording video is more complicated, but possible
private readonly CameraCaptureTask cameraTask;public Init() {
cameraTask = new CameraCaptureTask();cameraTask.Completed += PhotoCaptured;
}public void TakePhoto() {
cameraTask.Show();}private async void PhotoCaptured (object sender, PhotoResult result) {
await Task.Run(() => {// Do something with the result...
});}
App Bar
The app bar is a good place to put frequently used commands
The Windows 8 app bar has few technical limitations
Certification standards may limit it
Phone has limited screen space
The app bar cannot take up too much space
Put additional commands on the menu
A Windows Phone 8 app bar with the menu expanded
A Windows 8 app bar with three buttons
App Bar
Windows Phone 8 App Bar
• One app bar at the bottom of the page
• Only four items allowed
• Put additional items on the menu
• No grouping
• ApplicationBar control inside
PhoneApplicationPage.ApplicationBar
• Set Mode to Default to show the app bar
when the page loads
• Set IsMenuEnabled to enable the menu
Windows 8 App Bar
• Two app bars: one bottom and one top
• Behaves like any container
• No menu
• Can group items in nested containers
• AppBar control inside Page.BottomAppBar or
Page.TopAppBar
• Set IsOpen to true to show the app bar when
the page loads
• Set IsSticky to true to force an app bar to
always remain open
App Bar (Windows 8)
<Page.BottomAppBar IsOpen="True"><AppBar x:Name="bottomAppBar" Opened="AppBar_Opened" Padding="10,0,10,0">
<Grid><StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Button Style="{StaticResource EditAppBarButtonStyle}" Click="Edit_Click"/><Button Style="{StaticResource RemoveAppBarButtonStyle}" Click="Remove_Click"/><Button Style="{StaticResource AddAppBarButtonStyle}" Click="Add_Click"/>
</StackPanel><StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource RefreshAppBarButtonStyle}" Click="Refresh_Click"/>
<Button Style="{StaticResource HelpAppBarButtonStyle}" Click="Help_Click"/></StackPanel>
</Grid></AppBar>
</Page.BottomAppBar>
App Bar (Windows Phone 8)
<phone:PhoneApplicationPage.ApplicationBar><shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" Mode="Default" Opacity="1.0">
<shell:ApplicationBarIconButton x:Name="btnTakePicture"IconUri="/Assets/Icons/camera.png" Click="btnTakePicture_Click" Text="Take Picture"/>
<shell:ApplicationBarIconButton x:Name="btnShareTask" IconUri="/Assets/Icons/share.png"Click="btnShareShareTask_Click" Text="Share Image"/>
<shell:ApplicationBarIconButton x:Name="btnStartCooking"IconUri="/Assets/Icons/alarm.png" Click="btnStartCooking_Click" Text="Start Cooking"/>
<shell:ApplicationBarIconButton x:Name="btnPinToStart" IconUri="/Assets/Icons/like.png"Click="btnPinToStart_Click" Text="Pin To Start"/>
</shell:ApplicationBar></phone:PhoneApplicationPage.ApplicationBar>
Launching Built-In AppsURI scheme Description
http:[URL] Launches the web browser and navigates to URL
mailto:[email address]Launches the email app and creates a new message.Note that the email is not sent until the user taps send.
ms-settings-accounts: Launches the Account Settings app.
ms-settings-airplanemode: Launches the Airplane Mode Settings app.
ms-settings-bluetooth: Launches the Bluetooth Settings app.
ms-settings-cellular: Launches the Cellular Settings app.
ms-settings-emailandaccounts: Launches the email and accounts settings app.
ms-settings-location: Launches the Location Settings app.
ms-settings-lock: Launches the Lock Screen settings app.
ms-settings-wifi: Launches the Wi-Fi Settings app.
Thank You..