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

Phone_81_Development_for_Absolute_Beginners

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

Before we develop our own implementation of the Execute() method, we’ll need to create a method that our Execute() method will call in our DataSource. To that end, I want to create a method that will accept an instance of Ritual, add today’s date to the Dates property (an ObservableCollection<Date>) and then save that change to the Phone’s storage. So, I implement the CompleteRitualToday() method as follows:

We’ll need to implement the AddDate() method for a given Ritual. I’ll add the AddDate() method to the Ritual class definition:

Windows Phone 8.1 Development for Absolute Beginners – Page 290

Now, back in the CompletedButtonClick class, I can (1) comment out the stubbed out code and simply return true always when asked whether this command can be executed, and (2) call the CompleteRitualToday() method I just implemented a moment ago in the DataSource class, passing in the input parameter and casting it to a Ritual. (3) I will have to make sure that I add a using statement for the DataModel namespace by using the Control + [dot] keyboard shortcut to display the Intellisense menu option:

Windows Phone 8.1 Development for Absolute Beginners – Page 291

Now that we’ve implemented the CompletedButtonClick command, we’ll need to add it as a property to our Ritual class. Therefore, any user interface property that binds to Ritual can invoke the command. We’ll call our property CompletedCommand which is of type ICommand. Naturally, we’ll need to add the using statement for System.Windows.Input using the Control +

[dot] keyboard shortcut to display the Intellisense menu option:

In the Ritual class’ constructor, we’ll need to create a new instance of CompletedbuttonClick and set it to our new CompletedCommand property. In this way, we wire up the property called by the user interface to the CompletedButtonClick class we created. Again, we’ll need to add a using statement to our DailyRitual.Commands namespace using the technique Control + [dot] keyboard shortcut.

Windows Phone 8.1 Development for Absolute Beginners – Page 292

Finally, in the constructor I’ll need to create a new instance of ObservableCollection<DateTime> and set it equal to Dates to properly initialize that property as well:

Now that I have everything in my data model wired up correctly for the new Command, I can use it in my XAML. I’ll update the MainPage’s CompletedButton by binding the Command to the CompletedCommand of the Ritual and binding the CommandParameter to the Ritual itself so that it gets properly sent into the Command and we know which Ritual the invoked command belongs to:

However, when we run the application, we’ll get an error clicking the “I Did This Today” button for a given Ritual. Why? Because the DataContractJsonSerializer does not know what to do with our new CompletedCommand property … it tried to persist it to JSON format, but it could not:

Windows Phone 8.1 Development for Absolute Beginners – Page 293

Therefore, we’ll need to adorn the CompletedCommand property with an attribute that will tell the DataContractJsonSerializer to ignore this property when serializing an instance of Ritual to

JSON. We’ll add the [IgnoreDataMember] attribute above the CompletedCommand property.

This will require we add the proper using statement (using the technique you should now be familiar with):

Important: Once you make this change, you will need to reset the data stored for the app because it corrupted. To do this, simply shut down the emulator completely. The next time you run your application in debug mode, the emulator will be refreshed and your old data will be removed. Your app should now work correctly.

Next, we’ll want to disable the “I Did This Today” button once it has been clicked. Furthermore, it should be disabled when we re-run the application a second and subsequent time on the

Windows Phone 8.1 Development for Absolute Beginners – Page 294

same day. Therefore, we’ll need to (a) implement INotifyPropertyChanged on the Ritual class to notify the user interface when the Dates property, an ObservableCollection of DateTime instances, contains today’s date, and (b) we’ll need to create a value converter that will be used to tell the user interface whether or not to enable the button based on whether or not the

Dates property contains today’s date.

We’ll start by implementing the INotifyPropertyChanged interface on the Ritual class:

And I’ll choose the keyboard shortcut to display Intellisense and implement the

INotifyPropertyChanged interface:

Once implemented, we’ll want to also add our helper method NotifyPropertyChanged() like so:

Windows Phone 8.1 Development for Absolute Beginners – Page 295

Finally, we’ll want to fire the event by calling NotifyPropertyChanged() from the AddDate() method. We’ll pass in the name of the property that caused the event to fire (i.e., “Dates”):

To prepare for the value converter, I’ll add the IsEnabled=”False” attribute / value setting. Soon, we’ll bind the value to a new Value Converter that will determine whether this should be true or false, depending on whether today’s date is in the Dates ObservableCollection<Date>:

I’ll create a new folder called ValueConverters:

Windows Phone 8.1 Development for Absolute Beginners – Page 296

… and I’ll add a new item into that folder, specifically (1) a Class (2) named

IsCompleteToBoolean.cs, and then I’ll (3) click the OK button in the Add New Item dialog to complete this operation:

Windows Phone 8.1 Development for Absolute Beginners – Page 297

First, I’ll need to implement the IValueConverter interface for this new class. I’ll use the usual technique to first add a using statement:

… and the same Control + [dot] technique to implement the interface:

… which should produce the following stubbed out implementation:

Windows Phone 8.1 Development for Absolute Beginners – Page 298

We’ll only implement the Convert() method. Here we expect the Dates property to be passed in as value. I’ll first need to cast the value parameter to an ObservableCollection<Date>. Then, I’ll merely call the Contains() extension method to determine whether DateTime.Today is part of that collection. If it is, return false (because we want to set the Button’s IsEnabled property to False, since we already clicked it once today) and if it is not present, then return true

(because we want to set the Button’s IsEnabled property true since we have NOT clicked the button today).

Now, back in the MainPage.xaml, we’ll add a new prefix for the ValueConverters namespace we created when we added the ValueConverters folder, and we’ll add a Page.Resources section, and a new <valueconverter> instance, giving it a key of the same name.

<Page x:Class="DailyRituals.MainPage"

. . .

xmlns:valueconverter="using:DailyRituals.ValueConverters"

. . .

>

<Page.Resources>

<valueconverter:IsCompleteToBooleanConverter x:Key="IsCompleteToBooleanConverter"

/>

<valueconverter:CompletedDatesToIntegerConverter x:Key="CompletedDatesToIntegerConverter" />

</Page.Resources>

Below that, we’ll modify our Button like so:

Windows Phone 8.1 Development for Absolute Beginners – Page 299

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