如何让你的UWP应用程序无缝调用几何作图

时间:2023-02-10 17:30:26

有时候需要编辑一些几何图形,如三角形,圆锥曲线等,在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界面是这样的(为突出重点,省去文本编辑功能代码):

如何让你的UWP应用程序无缝调用几何作图

在“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后是这样的:

 如何让你的UWP应用程序无缝调用几何作图

在几何作图完成后,点击返回按钮:

 如何让你的UWP应用程序无缝调用几何作图

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是这样的了:

如何让你的UWP应用程序无缝调用几何作图

可以看到在得到的几何图上新出现了一个“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);
}

 

 

完整的代码如下:

如何让你的UWP应用程序无缝调用几何作图如何让你的UWP应用程序无缝调用几何作图
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);
}
}
}
View Code

 

如果你连拷贝代码都懒得话,就下载这个sample的压缩文件吧!