Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Phone_81_Development_for_Absolute_Beginners

.pdf
Скачиваний:
34
Добавлен:
10.02.2015
Размер:
18.77 Mб
Скачать

<TextBlock Text="55" FontSize="18" /> <TextBlock Text="Low: " FontSize="14" /> <TextBlock Text="32" FontSize="18" /> </StackPanel>

</StackPanel> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>

</StackPanel> </ScrollViewer>

As you can see, we’re employing a ScrollViewer to allow us to scroll past the bottom of the viewable area. It wraps a StackPanel that contains a ListView. In retrospect, a GridView may have worked as well if not better in this situation. The ListView is bound to the ViewModel. The ListView’s DataTemplate is made up of a series of StackPanels with TextBlocks and an Image. The only data item we’re binding to at the moment is the Date, but even that is in need of a little massaging to make it look correct. Ultimately, we’ll want to bind the source of the Image based on the Weater enum, and we’ll determine the high and low temperatures for a given day all using Value Converters.

I’ll add a new class to the project called DateToStringConverter.

First, I’ll make the class public and I’ll require it to implement IValueConverter. Once I’ve added that code,

public class DateToStringConverter : IValueConverter

{

}

Next, with my text cursor on the term IValueConverter I’ll use the Command [dot] shortcut to display the Intellisense menu:

… which will allow me to choose to Implement the interface by hitting the [Enter] key on my keyboard. My class now looks like this:

public class DateToStringConverter : IValueConverter

{

Windows Phone 8.1 Development for Absolute Beginners – Page 260

public object Convert(object value, Type targetType, object parameter, string language)

{

throw new NotImplementedException();

}

public object ConvertBack(object value, Type targetType, object parameter, string language)

{

throw new NotImplementedException();

}

}

As you can see, two method stubs are added to the class by implementing the IValueConverter. Convert will perform the conversion to your target display value, ConvertBack will do the opposite. In our case, we merely need to format the Date into a string with the format I desire, so I implement like so:

public class DateToStringConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, string language)

{

DateTime date = (DateTime)value;

return String.Format("{0:dddd} - {0:d}", date);

}

public object ConvertBack(object value, Type targetType, object parameter, string language)

{

//For "display only", I don't bother implementing ConvertBack

//HOWEVER if your planning on two-way binding, then you must. throw new NotImplementedException();

}

}

Note that a better / more complete example of a ValueConverter that takes into account the language / culture as well as the converter parameter is found here:

http://msdn.microsoft.com/enus/library/windows/apps/windows.ui.xaml.data.ivalueconverter

Windows Phone 8.1 Development for Absolute Beginners – Page 261

Next, I’ll need to tell my MainPage.xaml to use this new converter (I’ll remove everything except what will be added or changed):

<Page

. . .

xmlns:valueconverter="using:ValueConverterExample"

. . .> <Page.Resources>

<valueconverter:DateToStringConverter x:Key="DateToStringConverter" /> </Page.Resources>

. . .

<TextBlock Text="{Binding Date, Converter={StaticResource DateToStringConverter}}" FontSize="24" />

In the Page declaration, I create a new namespace. In this specific case I didn’t have to do this because the Value Converter I created is in the same namespace as the local namespace that’s already defined in the page. However, at some point I plan on moving my Value Converters into a folder and will change their namespace accordingly. Therefore, I’ve added this as a reminder / placeholder to myself.

Next, I add the Value Converter key “DateToStringConverter” and point it to the class named DateToStringConverter (inside the namespace that is aliased to “valueconverter”.

Third, I use the value converter in my TextBlock, inside the binding expression.

Testing the result provides the format we desire.

Next, I’ll add a value converter that will be used to change the Image’s source. I’ll use

the same basic procedure as before to create a new value converter called

WeatherEnumToImagePathConverter. A bit wordy, admittedly, but very descriptive. I’ll

implement it like so:

public class WeatherEnumToImagePathConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, string language)

{

var weather = (Weather)value;

Windows Phone 8.1 Development for Absolute Beginners – Page 262

var path = String.Empty;

switch (weather)

{

case Weather.Sunny:

path = "assets/sunny.png"; break;

case Weather.Cloudy:

path = "assets/cloudy.png"; break;

case Weather.Rainy:

path = "assets/rainy.png"; break;

case Weather.Snowy:

path = "assets/snowy.png"; break;

default: Break;

}

return path;

}

public object ConvertBack(object value, Type targetType, object parameter, string language)

{

throw new NotImplementedException();

}

}

Hopefully you see a pattern. I am merely taking the value, casting it to the original type I am expecting, then performing some logic or formatting on the value to determine the end result. In this case, I’m returning the path to the image I’ll use in the Image’s source.

I’ll now add the code to the XAML to implement this:

. . .

<Page.Resources>

. . .

<valueconverter:WeatherEnumToImagePathConverter x:Key="WeatherEnumToImagePathConverter" /> </Page.Resources>

. . .

Windows Phone 8.1 Development for Absolute Beginners – Page 263

<Image Source="{Binding Weather,

Converter={StaticResource WeatherEnumToImagePathConverter}}" Width="100"

Height="100" />

Running the app will display each of the icons at least once.

Next, I’ll determine the high and the low for each day. Recall that each day’s forecast contains an ObservableCollection<TimeForecast> that represent the temperature for each hour. All we need to do is look at that collection and find the highest number (or lowest number) and return those from our Value Converter. A simple LINQ query will do the trick in each case.

I’ll add two more classes,

HourlyCollectionToDailyHighConverter

HourlyCollectionToDailyLowConverter

Here’s the HourlyCollectionToDailyHighConverter:

public class HourlyCollectionToDailyHighConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, string language)

{

var hourly = (ObservableCollection<TimeForecast>)value;

return hourly

.OrderByDescending(p => p.Temperature)

.FirstOrDefault()

.Temperature;

}

. . .

}

And the HourlyCollectionToDailyLowConverter:

public class HourlyCollectionToDailyLowConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, string language)

{

Windows Phone 8.1 Development for Absolute Beginners – Page 264

var hourly = (ObservableCollection<TimeForecast>)value;

return hourly

.OrderBy(p => p.Temperature)

.FirstOrDefault()

.Temperature;

}

public object ConvertBack(object value, Type targetType, object parameter, string language)

{

throw new NotImplementedException();

}

}

And now I’ll add them to the XAML:

<Page.Resources>

. . .

<valueconverter:HourlyCollectionToDailyHighConverter x:Key="HourlyCollectionToDailyHighConverter" /> <valueconverter:HourlyCollectionToDailyLowConverter x:Key="HourlyCollectionToDailyLowConverter" /> </Page.Resources>

<TextBlock Text="High: " FontSize="14" /> <TextBlock Text="{Binding HourlyForecast,

Converter={StaticResource HourlyCollectionToDailyHighConverter}}" FontSize="18" />

<TextBlock Text="Low: " FontSize="14" /> <TextBlock Text="{Binding HourlyForecast,

Converter={StaticResource HourlyCollectionToDailyLowConverter}}" FontSize="18" />

Now, when you run the completed app, the results are essentially the same (from an aesthetic perspective) however the data is being pulled from our View Model and shaped appropriately into what we need for our View.

Recap

Value Converters allow us to shape the data items of our View Model into the format need to correctly bind to our View. You can merely format the data item, or change it completely. We’ll use this technique as we build a complete example in the next lesson.

Windows Phone 8.1 Development for Absolute Beginners – Page 265

Windows Phone 8.1 Development for Absolute Beginners – Page 266

Lesson 26: Exercise: The Daily Rituals App

In this exercise we’ll build a project that combines many of the things we talked about previously into a single example. The Daily Rituals project is essentially it's a goal-tracking app. The idea is, for 30 days, you'll track your progress against all the goals you've created.

For example, I'll create a new ritual or goal for myself. I’ll click the + Add icon in the Command Bar …

Which allows me to add a new Ritual. I’ll create dummy data for this demo, the Goal Name “Ritual 1” and the Goal Description: “Description of my new ritual”, and I will click the Add button …

Windows Phone 8.1 Development for Absolute Beginners – Page 267

I’ll return to the main screen where I can see a list of rituals. (I’ve added a second one in the screen shot, below):

Windows Phone 8.1 Development for Absolute Beginners – Page 268

I can click the “I Did This Today” button which will keep track of the days I completed this goal and it will show progress on a Progress Control below the Ritual. The progress bar will fill up over 30 days of establishing these daily rituals.

I’ll begin by (1) creating a new Blank App project (2) called Daily Rituals. (3) I’ll click the OK button on the New Project dialog to create the project.

Windows Phone 8.1 Development for Absolute Beginners – Page 269

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]