有时候需要编辑一些几何图形,如三角形,圆锥曲线等,在UWP应用中加入这些几何作图功能是件费时间又很难做好的事。其实Windows 10 应用商店中已有一些专业的几何作图工具了,那么能借来一用吗?答案是肯定的。
UWP中,微软为Windows.System.Launcher启动器新增了很多的功能,以前只能启动App,打开指定扩展名文件,对uri协议的解析,以及当启动的应用没有安装时则会提示前往商店下载等。
如今,微软丰富了Launcher的功能,通过新增的LaunchUriForResultsAsync API,Windows应用程序可以相互启动并交换数据和文件。利用这个新的API,使得以前需要多个App才能完成的复杂任务现在可以无缝的进行处理,使用户根本无法感觉到应用之间的切换。比如我们可以构想这么一个场景:在一个文本编辑APP中打开一个几何作图APP,完成几何作图后返回几何图片及数据到文本编辑APP。然后点击该图片即可以再次启动几何作图APP编辑几何图形,编辑图形完成后,传递新的图片返回原APP。
首先我们需要从Windows 10 应用商店中安装一个几何作图APP。这里以“活动几何”APP为例,选择它的原因是:1.免费;2.有中文界面;3功能足够。
然后我们就可以上代码了:
Xaml 代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Margin="20"> <Button x:Name="DoTest" Content="Do test" Click="DoTest_Click" /> <CheckBox x:Name="IsIncludeProcess" Content="IncludeProcess" IsChecked="True" /> <TextBlock x:Name="ShowMessage" Foreground="Red" /> <Button x:Name="DoEdit" Content="Edit the Geometry" Click="DoEdit_Click" Visibility="Collapsed" /> <ScrollViewer Height="600" Width="800" > <Image x:Name="ShowImage" /> </ScrollViewer> </StackPanel> </Grid>
我们的Sample App界面是这样的(为突出重点,省去文本编辑功能代码):
在“Do test”按钮点击事件函数中:
定义一个LauncherOptions变量,设置属性TargetApplicationPackageFamilyName 为该几何作图APP的PackageFamilyName,这里为62301LeonLi.ActiveGeometry_496e9sjp76zt6 :
var options = new LauncherOptions(); options.TargetApplicationPackageFamilyName = "62301LeonLi.ActiveGeometry_496e9sjp76zt6";
定义一个启动Uri变量:
Uri uri = new Uri("ag.editgeometry:?");
还需要一个传入参数的ValueSet变量 inputData:
ValueSet inputData = new ValueSet();
这样就可以调用LaunchUriForResultsAsync函数启动几何作图APP并将返回结果赋值给LaunchUriResult变量:
LaunchUriResult resultData = await Launcher.LaunchUriForResultsAsync(uri, options, inputData);
启动该几何作图APP后是这样的:
在几何作图完成后,点击返回按钮:
resultData的属性Status 为 LaunchUriStatus.Success 的话,就表示成功了。下面的代码是对返回的结果进行处理:
ValueSet theValues = resultData.Result; var resultState = theValues["ReturnedState"] as string; switch (resultState) { case "Success": if (theValues.ContainsKey("ImgFileToken")) { var tokenObject = theValues["ImgFileToken"]; if (tokenObject != null) { var token = tokenObject.ToString(); var imgFile = await SharedStorageAccessManager.RedeemTokenForFileAsync(token); if (imgFile != null) { try { IRandomAccessStream imageStream = await imgFile.OpenReadAsync(); BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(imageStream); ShowImage.Source = bitmapImage; } finally { } } } } if (theValues.ContainsKey("DataFileToken")) { var tokenObject = theValues["DataFileToken"]; if (tokenObject != null) { var token = tokenObject.ToString(); var dataFile = await SharedStorageAccessManager.RedeemTokenForFileAsync(token); if (dataFile != null) { var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; file_demonstration = await dataFile.CopyAsync(localFolder); DoEdit.Visibility = Visibility.Visible; } } } ShowMessage.Text = "Success"; break; } }
StorageFile file_demonstration;
imgFile是传回的图片文件,可以将该图片插入你想要的地方;dataFile是相应的数据文件,将该文件拷贝到你自己APP的目录下,用文件变量file_demonstration记住它,如果选择了“IsIncludeProcess”,则该文件中还包括了作图过程的数据。现在Sample App是这样的了:
可以看到在得到的几何图上新出现了一个“Edit the Geometry”按钮,这是用于再次编辑该几何图形的:
private async void DoEdit_Click(object sender, RoutedEventArgs e) { if (file_demonstration == null) return; var token = SharedStorageAccessManager.AddFile(file_demonstration); ValueSet inputData = new ValueSet(); inputData.Add("EditFileToken", token); await EditGeometry(true, inputData); }
完整的代码如下:
namespace CallEditGeometryAppSample { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private async void DoTest_Click(object sender, RoutedEventArgs e) { EditGeometry(true); } public async void EditGeometry(bool needResult) { bool isNew = true; ValueSet inputData = new ValueSet(); if (isNew) { } else { FileOpenPicker openPicker = new FileOpenPicker(); openPicker.ViewMode = PickerViewMode.List; openPicker.FileTypeFilter.Add(".sam"); openPicker.FileTypeFilter.Add(".sdz"); var gpxFile = await openPicker.PickSingleFileAsync(); if (gpxFile == null) { return; } var token = SharedStorageAccessManager.AddFile(gpxFile); inputData.Add("EditFileToken", token); } await EditGeometry(needResult, inputData); } private async System.Threading.Tasks.Task EditGeometry(bool needResult, ValueSet inputData) { var options = new LauncherOptions(); options.TargetApplicationPackageFamilyName = "62301LeonLi.ActiveGeometry_496e9sjp76zt6"; Uri uri = new Uri("ag.editgeometry:?"); if (!needResult) { await Launcher.LaunchUriAsync(uri, options, inputData); ShowMessage.Text = "No Reuslt Success"; } else { if (!IsIncludeProcess.IsChecked.Value) { inputData.Add("IncludeProcess", "N"); } LaunchUriResult resultData = await Launcher.LaunchUriForResultsAsync(uri, options, inputData); ShowMessage.Text = resultData.Status.ToString(); if (resultData.Status == LaunchUriStatus.Success && resultData.Result != null && resultData.Result.ContainsKey("ReturnedState")) { ValueSet theValues = resultData.Result; var resultState = theValues["ReturnedState"] as string; switch (resultState) { case "Success": if (theValues.ContainsKey("ImgFileToken")) { var tokenObject = theValues["ImgFileToken"]; if (tokenObject != null) { var token = tokenObject.ToString(); var imgFile = await SharedStorageAccessManager.RedeemTokenForFileAsync(token); if (imgFile != null) { try { IRandomAccessStream imageStream = await imgFile.OpenReadAsync(); BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(imageStream); ShowImage.Source = bitmapImage; } finally { } } } } if (theValues.ContainsKey("DataFileToken")) { var tokenObject = theValues["DataFileToken"]; if (tokenObject != null) { var token = tokenObject.ToString(); var dataFile = await SharedStorageAccessManager.RedeemTokenForFileAsync(token); if (dataFile != null) { var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; file_demonstration = await dataFile.CopyAsync(localFolder); DoEdit.Visibility = Visibility.Visible; } } } ShowMessage.Text = "Success"; break; case "Error": var resultMessage = theValues["ReturnedMessage"] as string; if (resultMessage == "Duplicate") { string mes = "Active Geometry has opened another windows. Please close it first."; ShowMessage.Text = mes; } var isCloseByOther = theValues["ByOtherClosed"] as string; if (isCloseByOther != "Y") { ShowMessage.Text += " --- By Other Closed"; } break; } } } } StorageFile file_demonstration; private async void DoEdit_Click(object sender, RoutedEventArgs e) { if (file_demonstration == null) return; var token = SharedStorageAccessManager.AddFile(file_demonstration); ValueSet inputData = new ValueSet(); inputData.Add("EditFileToken", token); await EditGeometry(true, inputData); } } }
如果你连拷贝代码都懒得话,就下载这个sample的压缩文件吧!