-1

我想创建类似 CameraCaptureUI.CaptureFileAsync 的东西,它将结果返回给调用者(在我的情况下,用户通过 bing 地图选择的位置)(这里问了同样的问题,但我仍然需要全屏 UI 或更完整的代码示例)

假设下一个用例:

  1. CallerPage1 Navigate-> CallerPage2 (通过 Frame.Navigate(typeof(CallerPage2)) )
  2. CallerPage2 Navigate-> LocationPickingPage (再次通过 Frame.Navigate(typeof(LocationPickingPage )) <- 这里应该是别的东西,但不是 Frame.Navigate)
  3. 用户选择一个位置并按下完成 -> 位置对象返回到 CallerPage2(通过 Frame.Navigate(typeof(CallerPage2)) )

现在,如果用户按下 CallerPage2,他/她将被导航回 LocationPickingPage,这在上述导航模型中是预期的,但我不会将他/她导航到 CallerPage1

这就是 CameraCaptureUI.CaptureFileAsync 的行为方式。也许有人可以帮助查看 CaptureFileAsync 或熟悉方法的“幕后”,并提供一些如何实现它的示例,以便可以像这样执行位置选择:

Location location = await new LocationPickCaptureUI.CaptureLocationAsync();

任何帮助,将不胜感激!

编辑

因此,也许有人可以了解页面如何在不影响导航历史的情况下共享数据。我只是在寻找类似 android 的 startActivityForResult 的东西。

我在这个问题上花了几天时间(msdn docs,研究不同的例子,论坛和不同的网站,包括这个),但没有找到任何方法,所以我认为是时候问自己的问题了。

以我正在寻找的方式在页面之间共享数据应该是显而易见的。也许我看错了,但问题仍然存在。

如果有人对我的问题投了反对票,请分享您的想法和知识来源,因为我仍然需要有关此问题的帮助。

提前致谢

4

1 回答 1

1

So, finally I've got an appropriate solution and maybe it can be helpful to anybody else.

The idea is to use Popup object and fit all the screen (however the details seemed like some kind of magic :) )

One thing: I used UserControl (in Visual Studio right click on project -> Add -> new item.. -> UserControl) template as in this scenario it is easy to manage popups's content

Here is the full source for C#:

CustomCaptureUI.xaml:

<UserControl
x:Class="Family.CustomCaptureUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Family"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="Root">

<Grid>
    <Border BorderBrush="Gray" BorderThickness="1">
        <Grid x:Name="Panel" Background="Gray">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="1" VerticalAlignment="Center">
                <TextBlock Text="New text" Foreground="LightGray" FontSize="18"/>
                <TextBox x:Name="ToDoText" Width="Auto" BorderBrush="Black" BorderThickness="1" VerticalAlignment="Center"/>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                    <Button x:Name="SubmitButton" Background="Gray" Content="Submit" HorizontalAlignment="Center"/>
                    <Button x:Name="CancelButton" Background="Gray" Content="Cancel" HorizontalAlignment="Center"/>
                </StackPanel>
            </StackPanel>
        </Grid>
    </Border>
</Grid>
</UserControl>

CustomCaptureUI.xaml.cs:

public sealed partial class CustomCaptureUI : UserControl
{
    public enum ResultStatuses
    {
        Canceled,
        Ok,
        None
    }

    public CustomCaptureUI()
    {
         _resultStatus = ResultStatuses.None;
        // force content's size to preferable value
        Root.Width = Window.Current.Bounds.Width;
        Root.Height = Window.Current.Bounds.Width * 0.3;
        // Init popup's Content
        _popup.Child = this;

        // Init popups's position
        _popup.SetValue(Canvas.LeftProperty, (Window.Current.Bounds.Width - Root.Width) * 0.5);
        _popup.SetValue(Canvas.TopProperty, (Window.Current.Bounds.Height - Root.Height) * 0.5);
    }

    public async Task<string> ShowDialog() 
    {
        string result = string.Empty;
        if (_semaphore != null) { DismissAddToDoPopup(); }

        // Init a Task for block the ShowDialog-method until user presses Cancel or Submit
        _semaphore = new Task(() => { });
        CancelButton.Click += (sender, e) =>
        {
            _resultStatus = ResultStatuses.Canceled;
            DismissAddToDoPopup();
        };
        SubmitButton.Click += (sender, e) =>
            {
                result = ToDoText.Text;
                _resultStatus = ResultStatuses.Ok;
                DismissAddToDoPopup();
            };

        ShowAddToDoPopup();

        // actual blocking of ShowDialog
        await _semaphore;
        return result;
    }

    public void DismissDialog() 
    {
        _resultStatus = ResultStatuses.Canceled;
        DismissAddToDoPopup();
    }

    private void ShowAddToDoPopup()
    {
        ToDoText.Text = string.Empty;
        _popup.IsOpen = true;
    }

    private void DismissAddToDoPopup()
    {
        if (_semaphore != null) 
        { 
            // starts the task and allows awaited ShowDialog-method to be released
            // after _semaphore is finishing
            _semaphore.Start();
            _semaphore = null;
        }
        _popup.IsOpen = false;
    }

    public ResultStatuses ResultStatus
    {
        get { return _resultStatus; }
    }


    private Popup _popup = new Popup();
    private Task _semaphore;
    private ResultStatuses _resultStatus;


}

And then it can be used like this:

        var dialog = new CustomCaptureUI();
        string result = await dialog.ShowDialog();
        if (dialog.ResultStatus == AddToDoDialog.ResultStatuses.Ok) 
        {
            // Useful stuff
            if (!string.IsNullOrWhiteSpace(result))
            {
               ...
            }
        }

Hope it can save someone's time a little

于 2012-10-11T13:27:15.857 回答