This post will show you how RadCloudJumpList, RadCloudDataForm and RadCloudPictureUpload can help you show a list of items; add new items; edit the existing ones and enhance them with pictures.
If you have followed the steps and created the application while reading the post you can continue from where we left and skip the current paragraph. Otherwise, you can quickly catch-up by downloading the application in its current state from here. You also need to go to Everlive.com, create a new storage app and fill its API key on the App.xaml.cs file as explained here.
public
class
Memory : EverliveDataItem
{
private
string
title;
private
string
details;
private
string
pictureUri;
private
DateTime date;
public
Memory()
{
this
.Date = DateTime.Now;
}
public
string
Title
{
get
{
return
this
.title;
}
set
{
if
(
this
.title != value)
{
this
.title = value;
this
.OnPropertyChanged(
"Title"
);
}
}
}
public
string
Details
{
get
{
return
this
.details;
}
set
{
if
(
this
.details != value)
{
this
.details = value;
this
.OnPropertyChanged(
"Details"
);
}
}
}
public
string
PictureUri
{
get
{
return
this
.pictureUri;
}
set
{
if
(
this
.pictureUri != value)
{
this
.pictureUri = value;
this
.OnPropertyChanged(
"PictureUri"
);
}
}
}
public
DateTime Date
{
get
{
return
this
.date;
}
set
{
if
(
this
.date != value)
{
this
.date = value;
this
.OnPropertyChanged(
"Date"
);
}
}
}
}
public
partial
class
ViewMemory : PhoneApplicationPage
{
private
Memory memory;
public
ViewMemory()
{
InitializeComponent();
}
protected
async
override
void
OnNavigatedTo(NavigationEventArgs e)
{
base
.OnNavigatedTo(e);
if
(
this
.NavigationContext.QueryString.ContainsKey(
"id"
))
{
string
id =
this
.NavigationContext.QueryString[
"id"
];
Guid guid =
new
Guid(id);
EverliveApp everliveApp = CloudProvider.Current.NativeConnection
as
EverliveApp;
this
.memory = await everliveApp.WorkWith().Data<Memory>().GetById(guid).ExecuteAsync();
this
.DataContext =
this
.memory;
if
(
this
.memory !=
null
)
{
return
;
}
}
await RadMessageBox.ShowAsync(
"Memory not found!"
);
}
}
<
Grid
x:Name
=
"ContentPanel"
Grid.Row
=
"1"
Margin
=
"12,0,12,0"
>
<
ScrollViewer
Margin
=
"12,0"
>
<
Grid
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
/>
</
Grid.RowDefinitions
>
<
Grid
>
<
Grid.RowDefinitions
>
<
RowDefinition
/>
<
RowDefinition
/>
</
Grid.RowDefinitions
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
TextBlock
Text
=
"{Binding Title}"
TextWrapping
=
"Wrap"
FontSize
=
"{StaticResource PhoneFontSizeExtraLarge}"
/>
<
TextBlock
Grid.Row
=
"1"
Text
=
"{Binding Date, StringFormat=\{0:d\}}"
Foreground
=
"{StaticResource PhoneSubtleBrush}"
FontSize
=
"{StaticResource PhoneFontSizeSmall}"
/>
<
Border
Grid.Column
=
"1"
Width
=
"132"
Height
=
"132"
Margin
=
"12,0,0,0"
VerticalAlignment
=
"Top"
Grid.RowSpan
=
"2"
>
<
Image
Stretch
=
"UniformToFill"
Source
=
"{Binding PictureUri}"
/>
</
Border
>
</
Grid
>
<
TextBlock
Grid.Row
=
"1"
Margin
=
"0,24"
Text
=
"{Binding Details}"
TextWrapping
=
"Wrap"
/>
</
Grid
>
</
ScrollViewer
>
</
Grid
>
<
Grid
x:Name
=
"ContentPanel"
Grid.Row
=
"1"
Margin
=
"12,0,12,0"
>
<
telerikCloud:RadCloudJumpList
Margin
=
"12"
x:Name
=
"jumpList"
ItemTap
=
"OnItemTap"
>
<
telerikCloud:RadCloudJumpList.ItemTemplate
>
<
DataTemplate
>
<
Grid
Margin
=
"0,0,0,24"
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
StackPanel
Margin
=
"0,-14,0,0"
>
<
TextBlock
MaxHeight
=
"56"
FontSize
=
"{StaticResource PhoneFontSizeExtraLarge}"
FontFamily
=
"{StaticResource PhoneFontFamilySemiLight}"
Foreground
=
"{StaticResource PhoneForegroundBrush}"
Text
=
"{Binding Title}"
TextWrapping
=
"Wrap"
/>
<
TextBlock
MaxHeight
=
"56"
FontSize
=
"{StaticResource PhoneFontSizeNormal}"
Foreground
=
"{StaticResource PhoneForegroundBrush}"
Text
=
"{Binding Details}"
Margin
=
"0,-4,0,4"
TextWrapping
=
"Wrap"
/>
<
TextBlock
FontSize
=
"{StaticResource PhoneFontSizeSmall}"
Text
=
"{Binding Date, StringFormat=\{0:d\}}"
Margin
=
"0,-2,0,0"
Foreground
=
"{StaticResource PhoneSubtleBrush}"
TextWrapping
=
"Wrap"
/>
</
StackPanel
>
<
Border
Grid.Column
=
"1"
Width
=
"132"
Height
=
"132"
VerticalAlignment
=
"Top"
Margin
=
"12,0,0,0"
>
<
Image
Stretch
=
"UniformToFill"
Source
=
"{Binding PictureUri}"
/>
</
Border
>
</
Grid
>
</
DataTemplate
>
</
telerikCloud:RadCloudJumpList.ItemTemplate
>
</
telerikCloud:RadCloudJumpList
>
</
Grid
>
EverliveCloudDataService<Memory> memoriesService;
public
Memories()
{
InitializeComponent();
this
.InitializeCloudService();
}
private
void
InitializeCloudService()
{
Expression<Func<Memory,
bool
>> expression = memory => memory.CreatedBy == CloudProvider.Current.CurrentUser.GetId();
this
.memoriesService =
new
EverliveCloudDataService<Memory>();
this
.memoriesService.Filter = expression;
this
.jumpList.CloudDataService = memoriesService;
}
private
void
OnItemTap(
object
sender, Telerik.Windows.Controls.ListBoxItemTapEventArgs e)
{
Guid itemId = (e.Item.Content
as
Memory).Id;
this
.NavigationService.Navigate(
new
Uri(
string
.Format(
"/Views/ViewMemory.xaml?id={0}"
, itemId), UriKind.RelativeOrAbsolute));
}
<
Grid
x:Name
=
"ContentPanel"
Grid.Row
=
"1"
Margin
=
"12,0,12,0"
>
<
ScrollViewer
>
<
telerikCloud:RadCloudDataForm
Success
=
"MemoryDataForm_Success"
Failed
=
"MemoryDataForm_Failed"
x:Name
=
"MemoryDataForm"
CurrentItem
=
"{Binding}"
>
<
Grid
>
<
telerikInput:DataField
TargetProperty
=
"Title"
>
<
telerikInput:DataField.Validators
>
<
telerikInput:NonEmptyStringValidator
/>
</
telerikInput:DataField.Validators
>
</
telerikInput:DataField
>
<
telerikInput:DataField
TargetProperty
=
"Date"
>
<
telerikInput:DataField.EditorStyles
>
<
Style
TargetType
=
"telerikInput:RadDatePicker"
>
<
Setter
Property
=
"OkButtonIconUri"
Value
=
"/Assets/AppBar/OK.png"
/>
<
Setter
Property
=
"CancelButtonIconUri"
Value
=
"/Assets/AppBar/Cancel.png"
/>
</
Style
>
</
telerikInput:DataField.EditorStyles
>
</
telerikInput:DataField
>
<
telerikInput:DataField
TargetProperty
=
"Details"
>
<
telerikInput:DataField.EditorStyles
>
<
Style
TargetType
=
"telerikPrimitives:RadTextBox"
>
<
Setter
Property
=
"AcceptsReturn"
Value
=
"True"
/>
<
Setter
Property
=
"MinHeight"
Value
=
"182"
/>
<
Setter
Property
=
"TextWrapping"
Value
=
"Wrap"
/>
</
Style
>
</
telerikInput:DataField.EditorStyles
>
</
telerikInput:DataField
>
</
Grid
>
</
telerikCloud:RadCloudDataForm
>
</
ScrollViewer
>
</
Grid
>
xmlns:telerikCloud="clr-namespace:Telerik.Windows.Controls.Cloud;assembly=Telerik.Windows.Controls.Cloud"
xmlns:telerikInput="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Input"
xmlns:telerikPrimitives="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Primitives"
xmlns:telerikDataForm="clr-namespace:Telerik.Windows.Controls.DataForm;assembly=Telerik.Windows.Controls.Input"
<
phone:PhoneApplicationPage.ApplicationBar
>
<
shell:ApplicationBar
>
<
shell:ApplicationBarIconButton
Text
=
"save"
IconUri
=
"/Assets/AppBar/Save.png"
Click
=
"OnSave_Click"
/>
<
shell:ApplicationBarIconButton
Text
=
"cancel"
IconUri
=
"/Assets/AppBar/Cancel.png"
Click
=
"OnCancel_Click"
/>
</
shell:ApplicationBar
>
</
phone:PhoneApplicationPage.ApplicationBar
>
protected
async
override
void
OnNavigatedTo(NavigationEventArgs e)
{
base
.OnNavigatedTo(e);
Memory memory;
if
(
this
.NavigationContext.QueryString.ContainsKey(
"id"
))
{
string
id =
this
.NavigationContext.QueryString[
"id"
];
Guid guid =
new
Guid(id);
EverliveApp everliveApp = CloudProvider.Current.NativeConnection
as
EverliveApp;
memory = await everliveApp.WorkWith().Data<Memory>().GetById(guid).ExecuteAsync();
}
else
{
this
.PageTitleBlock.Text =
"add"
;
memory =
new
Memory();
}
this
.DataContext = memory;
}
private
void
OnSave_Click(
object
sender, EventArgs e)
{
this
.MemoryDataForm.Commit();
}
private
void
OnCancel_Click(
object
sender, EventArgs e)
{
this
.NavigationService.GoBack();
}
private
void
MemoryDataForm_Success(
object
sender, EventArgs e)
{
PhoneApplicationService.Current.State[
"ReloadMemories"
] =
true
;
this
.NavigationService.GoBack();
}
private
async
void
MemoryDataForm_Failed(
object
sender, EventArgs e)
{
await RadMessageBox.ShowAsync(
"Memory can’t be saved. Please try again later."
);
}
protected
override
void
OnNavigatedTo(NavigationEventArgs e)
{
base
.OnNavigatedTo(e);
if
(e.NavigationMode == NavigationMode.Back && PhoneApplicationService.Current.State.ContainsKey(
"ReloadMemories"
))
{
PhoneApplicationService.Current.State.Remove(
"ReloadMemories"
);
jumpList.ReloadCloudItemsAsync();
}
}
<
shell:ApplicationBar.Buttons
>
<
shell:ApplicationBarIconButton
Text
=
"new"
IconUri
=
"/Assets/AppBar/Add.png"
Click
=
"OnNewMemoryButton_Click"
/>
</
shell:ApplicationBar.Buttons
>
private
void
OnNewMemoryButton_Click(
object
sender, EventArgs e)
{
this
.NavigationService.Navigate(
new
Uri(
"/Views/AddOrEditMemory.xaml"
, UriKind.RelativeOrAbsolute));
}
<
phone:PhoneApplicationPage.ApplicationBar
>
<
shell:ApplicationBar
>
<
shell:ApplicationBarIconButton
Text
=
"edit"
IconUri
=
"/Assets/AppBar/Edit.png"
Click
=
"OnEditButton_Click"
/>
<
shell:ApplicationBarIconButton
Text
=
"delete"
IconUri
=
"/Assets/AppBar/Delete.png"
Click
=
"OnDeleteButton_Click"
/>
</
shell:ApplicationBar
>
</
phone:PhoneApplicationPage.ApplicationBar
>
private
void
OnEditButton_Click(
object
sender, EventArgs e)
{
this
.NavigationService.Navigate(
new
Uri(
string
.Format(
"/Views/AddOrEditMemory.xaml?id={0}"
,
this
.memory.Id), UriKind.RelativeOrAbsolute));
}
private
async
void
OnDeleteButton_Click(
object
sender, EventArgs e)
{
MessageBoxClosedEventArgs args = await RadMessageBox.ShowAsync(
"Delete memory?"
,
"Deleting memory"
, MessageBoxButtons.OKCancel);
if
(args.Result == DialogResult.OK)
{
EverliveApp app = CloudProvider.Current.NativeConnection
as
EverliveApp;
await app.WorkWith().Data<Memory>().Delete(
this
.memory.Id).TryExecuteAsync();
PhoneApplicationService.Current.State[
"ReloadMemories"
] =
true
;
this
.NavigationService.GoBack();
}
}
<
telerikInput:DataField
Header
=
""
Margin
=
"12"
TargetProperty
=
"PictureUri"
>
<
telerikInput:DataField.CustomEditor
>
<
telerikDataForm:CustomEditor
>
<
telerikCloud:RadCloudPictureUpload
telerikDataForm:CustomDataField.IsEditor
=
"True"
telerikDataForm:CustomDataField.EditorValuePath
=
"PictureUri"
EmptyContent
=
"no image"
PixelHeight
=
"300"
PixelWidth
=
"300"
Height
=
"132"
Width
=
"132"
HorizontalAlignment
=
"Left"
>
<
telerikCloud:RadCloudPictureUpload.EmptyContentTemplate
>
<
DataTemplate
>
<
Grid
Width
=
"132"
Height
=
"132"
Background
=
"Gray"
>
<
TextBlock
VerticalAlignment
=
"Bottom"
Margin
=
"12"
FontFamily
=
"{StaticResource PhoneFontFamilySemiLight}"
FontSize
=
"{StaticResource PhoneFontSizeLarge}"
Text
=
"{Binding}"
TextWrapping
=
"Wrap"
/>
</
Grid
>
</
DataTemplate
>
</
telerikCloud:RadCloudPictureUpload.EmptyContentTemplate
>
</
telerikCloud:RadCloudPictureUpload
>
</
telerikDataForm:CustomEditor
>
</
telerikInput:DataField.CustomEditor
>
</
telerikInput:DataField
>
If you still haven't tried Cloud Controls for Windows Phone, you can read how to download the CTP here. Last week we’ve also released an Examples application which demonstrates common usage scenarios with all of the Cloud Controls.