uvp作业2

3.19日作业-uwp开发技术精选

前言

这个文件是由manager小组完成的,小组成员:范坤、高志远、陈思源、龙仕。我们分别用了数据分享、数据绑定、邮件发送、文件处理这四种技术

一: 分享数据

共享合同是一种在应用程序之间快速共享数据(如文本,链接,照片和视频)的简便方法。例如,用户可能想要使用社交网络应用与他们的朋友共享网页,或者在笔记应用中保存链接以便稍后参考。
###设置事件处理程序:

(1)添加DataRequested事件处理程序,以便在用户调用共享时调用。当用户点击您的应用中的控件(例如按钮或应用栏命令)或在特定场景中自动(例如,如果用户完成关卡并获得高分)时,就会发生这种情况。

DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += DataTransferManager_DataRequested;

(2)当DataRequested事件发生时,您的应用程序收到DataRequest对象。它包含一个DataPackage,您可以使用它来提供用户想要共享的内容。您必须提供要分享的标题和数据。描述是可选的,但建议使用。

DataRequest request = args.Request;

选择数据:

DataPackage对象可以包含这些格式的一个或多个,以任何组合。

  1. Plain text 纯文本
  2. Uniform Resource Identifiers (URIs) 统一资源标识符(URI)
  3. HTML
  4. Formatted text 格式化文本
  5. Bitmaps 位图
  6. Files 文件
  7. Custom developer-defined data 自定义开发人员定义的数据

设置属性:

打包数据以进行共享时,您可以提供各种属性,以提供有关正在共享的内容的其他信息。这些属性可帮助目标应用改善用户体验。例如,当用户与多个应用程序共享内容时,描述会有所帮助。在共享图像或指向网页的链接时添加缩略图可为用户提供可视参考。有关更多信息,请参阅DataPackagePropertySet。
除标题外的所有属性都是可选的。title属性是必需的,必须设置。

request.Data.Properties.Title = "Share Example";
request.Data.Properties.Description = "A demonstration on how to share";

启动共享UI

系统提供用于共享的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();
    }

点击share
uvp作业2_第1张图片


共享图片成功
uvp作业2_第2张图片

二:简单的数据绑定

为什么需要数据绑定?

  1. 开发人员,需要把数据从数据存储的地方检索出来,呈现给用户。为实现这一过程,开发人员不得不编写自定义代码以图形的方式绘制这些数据,或者手工将这些数据赋值给控件属性来显示它,使用这种方式来显示数据,对于不同的情况、不同的类型的数据以及不同类型的显示方式来说,处理方法都是不同的。
  2. 如果还要通过用户界面允许用户与数据交换以及修改或添加,就必需编写自定义代码从用户界面收集修改过的数据值,并将这些数据永久保存到数据原来存储的地方。这一过程要求我们编写大量复杂的并容易出错的代码,所以我们渴望出现一个更好的解决方案。
  3. 数据绑定将所有的这些步骤封装进一些组件,来帮组显示这些数据,有了这些组件,就会减少需要编写的代码数量。数据绑定 还提供一些容易理解的模式,来规范编写代码的方法将数据挂接到可以显示和编辑数据的控件。

演示:

将TextBlock、ListView等控件绑定到Recording等类的属性上,将这些属性显示出来,并且能随其变化而变化。

  • 首先将Recording.cs添加到你的新建空项目Quickstart里,内容如下。
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对象的某一属性绑定,直接显示该属性。


最终效果图:

uvp作业2_第3张图片

uvp作业2_第4张图片
uvp作业2_第5张图片

uvp作业2_第6张图片

三:发送电子邮件

个人小管家涉及到备忘录、提醒事项,所以提醒功能必不可少。一般来说提醒功能在PC端可以是闹铃、弹出提醒框或者发邮件。如果你的事务不是特别紧急的话,发邮件是一个特别好的选择,它不是打扰行的,不会在你正在思考的时候打断你,只需在工作之余浏览邮件时即可。

设置联系人

获取联系人

UWP中联系人获取需要引入Windows.ApplicationModel.Contacts名称空间。

选择联系人

选择联系人有两种方式。一种是调用WIN10的人脉选择联系人,UWP提供了ContactPicker控件用来选取一个或者多个联系人;另一种是自己指定联系人(邮件地址)。一般提醒自己可以默认指定自己的邮箱地址,当然也可以通知其他人。

调用WIN10人脉选择联系人
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);
    }
}

在这里插入图片描述
uvp作业2_第7张图片

指定联系人
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);

效果如下:

uvp作业2_第8张图片

启动撰写电子邮件对话框

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);

最终效果如下:
uvp作业2_第9张图片

总结

  1. 在发送邮件的时候出现了一个问题,而且是最大的问题,邮件竟然一直在发送中,发送不出去,仍未解决。。。。

  2. 如果只是直接发给自己或者某个人的话,其实没必要出现电子邮件对话框,而且耽误时间。所以想尝试把出现对话框给删掉,等能发送的话看看结果

四:文件处理

我们的个人小管家项目感觉不仅需要使用数据库,而且需要一些本地访问文件的手段,所以,挑选了一些文件处理的功能详细情况如下:
主要用到的类有:

  1. StorageFolder 类
  2. StorageFile 类
  3. FileIO 类

创建文件

 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);
    }

你可能感兴趣的:(可视化程序设计)