这个文件是由manager小组完成的,小组成员:范坤、高志远、陈思源、龙仕。我们分别用了数据分享、数据绑定、邮件发送、文件处理这四种技术
共享合同是一种在应用程序之间快速共享数据(如文本,链接,照片和视频)的简便方法。例如,用户可能想要使用社交网络应用与他们的朋友共享网页,或者在笔记应用中保存链接以便稍后参考。
###设置事件处理程序:
(1)添加DataRequested事件处理程序,以便在用户调用共享时调用。当用户点击您的应用中的控件(例如按钮或应用栏命令)或在特定场景中自动(例如,如果用户完成关卡并获得高分)时,就会发生这种情况。
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += DataTransferManager_DataRequested;
(2)当DataRequested事件发生时,您的应用程序收到DataRequest对象。它包含一个DataPackage,您可以使用它来提供用户想要共享的内容。您必须提供要分享的标题和数据。描述是可选的,但建议使用。
DataRequest request = args.Request;
DataPackage对象可以包含这些格式的一个或多个,以任何组合。
打包数据以进行共享时,您可以提供各种属性,以提供有关正在共享的内容的其他信息。这些属性可帮助目标应用改善用户体验。例如,当用户与多个应用程序共享内容时,描述会有所帮助。在共享图像或指向网页的链接时添加缩略图可为用户提供可视参考。有关更多信息,请参阅DataPackagePropertySet。
除标题外的所有属性都是可选的。title属性是必需的,必须设置。
request.Data.Properties.Title = "Share Example";
request.Data.Properties.Description = "A demonstration on how to share";
系统提供用于共享的UI。要启动它,请调用ShowShareUI方法。
DataTransferManager.ShowShareUI();
在MainPage.xaml中添加一个按钮并设置相应事件
在MainPage.xaml.cs文件中添加代码
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
//使ShareRequested函数在共享操作时发生
DataTransferManager.GetForCurrentView().DataRequested += ShareRequested;
}
private void Mybutton_OnClick(object sender, RoutedEventArgs e)
{
DataTransferManager.ShowShareUI();
}
private void ShareRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var deferral = args.Request.GetDeferral();
DataRequest request = args.Request;
request.Data.Properties.Title = "ShareUISample";
request.Data.SetText("Description:" + "This is a line from ShareUISample. Welcome to learn UWP.");
//flash.jpg是示例代码中Asssets文件夹中的图片,可以将其改为你自己的图片
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/flash.jpg")));
deferral.Complete();
}
将TextBlock、ListView等控件绑定到Recording等类的属性上,将这些属性显示出来,并且能随其变化而变化。
namespace Quickstart
{
public class Recording
{
public string ArtistName { get; set; }
public string CompositionName { get; set; }
public DateTime ReleaseDateTime { get; set; }
public Recording()
{
this.ArtistName = "Wolfgang Amadeus Mozart";
this.CompositionName = "Andante in C for Piano";
this.ReleaseDateTime = new DateTime(1761, 1, 1);
}
public string OneLineSummary
{
get
{
return $"{this.CompositionName} by {this.ArtistName}, released: "
+ this.ReleaseDateTime.ToString("d");
}
}
public class RecordingViewModel
{
private Recording defaultRecording = new Recording();
public Recording DefaultRecording { get { return this.defaultRecording; } }
private ObservableCollection recordings = new ObservableCollection();
public ObservableCollection Recordings { get { return this.recordings; } }
public RecordingViewModel()
{
this.recordings.Add(new Recording()
{
ArtistName = "Johann Sebastian Bach",
CompositionName = "Mass in B minor",
ReleaseDateTime = new DateTime(1748, 7, 8)
});
this.recordings.Add(new Recording()
{
ArtistName = "Ludwig van Beethoven",
CompositionName = "Third Symphony",
ReleaseDateTime = new DateTime(1805, 2, 11)
});
this.recordings.Add(new Recording()
{
ArtistName = "George Frideric Handel",
CompositionName = "Serse",
ReleaseDateTime = new DateTime(1737, 12, 3)
});
}
}
}
}
代码定义了类Recording,RecordingViewModel。Recording是绑定源,而RecordingViewModel是为了方便绑定而设置的类。
代码还使用了通用 ObservableCollection
类,这个类是数据绑定的一个很好的集合选择,因为它实现了 INotifyPropertyChanged 和 INotifyCollectionChanged 接口。 当添加或删除项目或者列表本身的属性更改时,这些接口将向绑定提供更改通知。
接下来,从表示标记页的类公开绑定源类。 我们通过将类型 RecordingViewModel 的属性添加到 MainPage 来执行此操作。
namespace Quickstart
{
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.ViewModel = new RecordingViewModel();
}
public RecordingViewModel ViewModel { get; set; }
}
}
最后更改MainPage.xaml
上例中的ListView与ViewModel.Recordings绑定,显示的是一组Recording对象的某一属性。
而TextBlock则与某个Recoring对象的某一属性绑定,直接显示该属性。
个人小管家涉及到备忘录、提醒事项,所以提醒功能必不可少。一般来说提醒功能在PC端可以是闹铃、弹出提醒框或者发邮件。如果你的事务不是特别紧急的话,发邮件是一个特别好的选择,它不是打扰行的,不会在你正在思考的时候打断你,只需在工作之余浏览邮件时即可。
UWP中联系人获取需要引入Windows.ApplicationModel.Contacts名称空间。
选择联系人有两种方式。一种是调用WIN10的人脉选择联系人,UWP提供了ContactPicker控件用来选取一个或者多个联系人;另一种是自己指定联系人(邮件地址)。一般提醒自己可以默认指定自己的邮箱地址,当然也可以通知其他人。
String subject = "test";
String messageBody = "test";
ContactPicker contactPicker = new ContactPicker();
contactPicker.SelectionMode = ContactSelectionMode.Fields;
contactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.Email);
contactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.Address);
contactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.PhoneNumber);
//Select one or more contacts
IList contacts = await contactPicker.PickContactsAsync();
if (contacts != null &&
contacts.Count > 0)
{
foreach (Contact contact in contacts)
{
await ComposeEmail(contact, subject, messageBody);
}
}
String subject = "test";
String messageBody = "test";
//Windows.ApplicationModel.Contacts.Contact
Contact contact = new Contact()
{
Emails =
{
new ContactEmail()
{
Address = "[email protected]",
Description = "UWP 开发者",
}
}
};
await ComposeEmail(contact, subject, messageBody);
效果如下:
private async Task ComposeEmail(Windows.ApplicationModel.Contacts.Contact recipient,
string subject, string messageBody)
{
var emailMessage = new Windows.ApplicationModel.Email.EmailMessage();
emailMessage.Body = messageBody;
var email = recipient.Emails.FirstOrDefault();
if (email != null)
{
var emailRecipient = new Windows.ApplicationModel.Email.EmailRecipient(email.Address);
emailMessage.To.Add(emailRecipient);
emailMessage.Subject = subject;
}
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(emailMessage);
}
此函数的第一个参数是联系人,第二个是主题,第三个是消息
因为此函数是async函数,所以调用时需要加await
await ComposeEmail(contact, subject, messageBody);
在发送邮件的时候出现了一个问题,而且是最大的问题,邮件竟然一直在发送中,发送不出去,仍未解决。。。。
如果只是直接发给自己或者某个人的话,其实没必要出现电子邮件对话框,而且耽误时间。所以想尝试把出现对话框给删掉,等能发送的话看看结果
我们的个人小管家项目感觉不仅需要使用数据库,而且需要一些本地访问文件的手段,所以,挑选了一些文件处理的功能详细情况如下:
主要用到的类有:
Create sample file; replace if exists.
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync("sample.txt",Windows.Storage.CreationCollisionOption.ReplaceExisting);
Debug.Write(""+storageFolder.Path);
下面介绍了如何使用 StorageFile 类在磁盘上写入可写文件。 每种写入文件(除非你在创建后立即写入文件)的方法的常见第一步是使用 StorageFolder.GetFileAsync 获取文件
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.GetFileAsync("sample.txt");
通过调用 FileIO 类的 WriteTextAsync 方法,将文本写入文件
await FileIO.WriteTextAsync(sampleFile, "Swift as a shadow");
调用 ConvertStringToBinary 以获取你想要写入文件的字节(基于随机字符串)的缓冲区
var buffer = Windows.Security.Cryptography.CryptographicBuffer.
ConvertStringToBinary("What fools these mortals be",
Windows.Security.Cryptography.BinaryStringEncoding.Utf8);
然后,通过调用 FileIO 类的 WriteBufferAsync 方法,将字节从你的缓冲区写入文件
await Windows.Storage.FileIO.WriteBufferAsync(sampleFile, buffer);
调用 StorageFile.OpenAsync 方法打开文件。 打开操作完成后,它将返回文件的内容流。
var stream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);
接下来,通过从 stream 调用 GetOutputStreamAt 方法获取输出流。 将其放到 using 语句中以管理输出流的生存期
using (var outputStream = stream.GetOutputStreamAt(0))
{
// We'll add more code here in the next step.
}
stream.Dispose(); // Or use the stream variable (see previous code snippet) with a using statement as well.
将此代码添加到现有的 using 语句中,以通过创建一个新的 DataWriter 对象和调用 DataWriter.WriteString 方法写入输出流
using (var dataWriter = new Windows.Storage.Streams.DataWriter(outputStream))
{
dataWriter.WriteString("DataWriter has methods to write to various types, such as DataTimeOffset.");
}
最后,添加此代码(在内部 using 语句中)以使用 StoreAsync 将文本保存到你的文件并使用 FlushAsync 关闭该流
await dataWriter.StoreAsync();
await outputStream.FlushAsync();
下面介绍了如何使用 StorageFile 类在磁盘上从文件进行读取。 每种从文件读取的方法的常见第一步是使用 StorageFolder.GetFileAsync 获取文件。
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.GetFileAsync("sample.txt");
通过调用 FileIO 类的 ReadTextAsync 方法,从文件读取文本
string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);
调用 FileIO 类的 ReadBufferAsync 方法
var buffer = await Windows.Storage.FileIO.ReadBufferAsync(sampleFile);
使用 DataReader 对象先读取缓冲区的长度,然后读取其内容
using (var dataReader = Streams.DataReader.FromBuffer(buffer))
{
string text = dataReader.ReadString(buffer.Length);
}
通过调用 StorageFile.OpenAsync 方法,为你的文件打开流。 操作完成后,它将返回文件的内容流
var stream = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
获取稍后要使用的流的大小
ulong size = stream.Size;
通过调用 GetInputStreamAt 方法获取输入流。 将其放到 using 语句中以管理流的生存期。 调用 GetInputStreamAt 时指定 0,以将位置设置在流的开头
using (var inputStream = stream.GetInputStreamAt(0))
{
// We'll add more code here in the next step.
}
最后,将此代码添加到现有的 using 语句中以在流上获取 DataReader 对象,然后通过调用 DataReader.LoadAsync 和 DataReader.ReadString 读取文本
using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream))
{
uint numBytesLoaded = await dataReader.LoadAsync((uint)size);
string text = dataReader.ReadString(numBytesLoaded);
}