Hatena::ブログ(Diary)

Atelier:Mitsuba

2012-02-07

その18:Searchパネルから値を取得する

Metro Style AppsにはShareの他にSearch機能があります。

Searchを使えば、アプリケーション外からアプリケーションに値を投げることができます。

挙動はこんなかんじ。

Shareと同じように、Searchパネルを表示するトグルボタンも作れます。

f:id:c-mitsuba:20120207210339p:image

検索バーが出るので、テキストを入力してEnter

値がアプリ内のTextBlockに入ります。

f:id:c-mitsuba:20120207210336p:image

もちろん、他のアプリケーションを開いているときでも検索できます。

Searchパネルでは検索したいアプリを選択して、検索できます。

f:id:c-mitsuba:20120207210330p:image


では、実装しましょう。これも簡単です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

//Searchパネルを使いたい時にUsing
using Windows.ApplicationModel.Search;

namespace Application24
{
    partial class MainPage
    {
        SearchPane searchPane;

        public MainPage()
        {
            InitializeComponent();

            //Searchパネルのオブジェクトを作成
            this.searchPane = SearchPane.GetForCurrentView();
            
            //検索があった時のイベントを登録
            this.searchPane.QuerySubmitted += new TypedEventHandler<SearchPane, SearchPaneQuerySubmittedEventArgs>(this.OnQuerySubmitted);

        }

        public void OnQuerySubmitted(object sender, SearchPaneQuerySubmittedEventArgs args)
        {
            //引数で降ってくるテキストを取得
            tb.Text = args.QueryText;
        }

        private void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedEventArgs e)
        {
            //Searchパネルを表示非表示するボタン
            this.searchPane.Show();
        }
    }
}

<UserControl x:Class="Application24.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">
    
    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button Tapped="Button_Tapped" Content="Show SeachPanel" Width="288" Height="100" HorizontalAlignment="Center" FontSize="30"></Button>
            <TextBlock Text="Seach Text" x:Name="tb" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="72"></TextBlock>
        </StackPanel>
    </Grid>
    
</UserControl>

最後に、Package.appmanifestのDeclarationsから、Searchパネルの利用を許可します。

これがないとビルドが通りません。

f:id:c-mitsuba:20120207210354p:image

ところで、なんで形名がSearchPaneなんやろう。。。

これ絶対たいぽやとおもうねんけど(


追記:これペインってよむんだって!ありがとうございます!

f:id:c-mitsuba:20120207212009p:image

http://eow.alc.co.jp/search?q=pane&ref=sa

英語よわいんがばれる。。。。!

その17:Shareを使ってTweet@ramaからつぶやく

Windows 8 Developer Previewなので正式版とは異なる場合があります。
また、Windows Updateが走るときもあるため、エントリ執筆現在の情報をもとにかいています。

MetroStyleAppsではShare機能を使えば、アプリ間でデータのやり取りを行うことができます。

こんなかんじ。

自作アプリのTextBoxに書いたテキストをShareしてー

f:id:c-mitsuba:20120207203135p:image

Tweet@ramaのTextBoxへ!

f:id:c-mitsuba:20120207203131p:image

しかもとっても簡単です。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

//Shareに使います。
using Windows.ApplicationModel.DataTransfer;

namespace Application23
{
    partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
//インスタンス化
            DataTransferManager datatransferManager;
            datatransferManager = DataTransferManager.GetForCurrentView();

//ShareするデータをShareパネルが取得するためのイベントを登録
            datatransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.DataRequested);
        }

        private void DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
//引数argsのプロパティにShareするデータを入れてく。
            args.Request.Data.Properties.Title = "Shareするデータのタイトル";
            args.Request.Data.Properties.Description = "副題";
            args.Request.Data.SetText(tb.Text);
        }

        private void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedEventArgs e)
        {
//Shareパネルはコントロールからトグルのように表示非表示できるよ
            DataTransferManager.ShowShareUI();
        }
    }
}


<UserControl x:Class="Application23.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">
    
    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <StackPanel Orientation="Vertical" Width="300">
                <TextBlock Text=" Text Share" Height="20" FontSize="18"></TextBlock>
                <TextBox x:Name="tb" Height="80" FontSize="18"></TextBox>
            </StackPanel>
            <Button Width="200" Height="100" Tapped="Button_Tapped" Content="Show Share" FontSize="24"></Button>
        </StackPanel>
    </Grid>
    
</UserControl>

この挙動からわかるように、Shareされた値の処理はShareされた先のアプリに依存します。

Tweet@ramaではargs.Request.Data.SetTextがTweetの本文でした。

他にもShare出来るデータは、画像だったりリンクだったりといろいろあります。

どの項目がどのように使われているかを調査して、項目によってより正しい値を入れるようにしないとダメですね。

その16:WebViewに現在表示されているURLを取得する

Windows 8 Developer Previewなので正式版とは異なる場合があります。
また、Windows Updateが走るときもあるため、エントリ執筆現在の情報をもとにかいています。

Windows Phoneでは、現在表示されているURLは以下のように取得することができます。

WebBrowser.Source;

しかしMetroStyleAppsでは、最初に表示されたSourceのみ取得することができ、この値が更新されません。

おそらくバグですね!

そのため、WebViewの機能にある、JSを使ったInvokeで取得します。

挙動としてはこんな感じ。

TextBlockをTapして値を更新します。

f:id:c-mitsuba:20120207194555p:image

ちゃんとgoogle.comが表示されます。

f:id:c-mitsuba:20120207194553p:image

しかし画面遷移しても、Sourceでひっぱった方は値がかわりません。

f:id:c-mitsuba:20120207194550p:image


MainPage.xaml

<UserControl x:Class="Application21.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">
    
    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <StackPanel>
            <TextBlock Text="WebView.Source" Height="100" x:Name="tbs" FontSize="20" Tapped="tbs_Tapped"></TextBlock>
            <WebView Height="400" x:Name="wv" Source="http://google.com"></WebView>
            <TextBlock Text="JSInvoke" Height="100" x:Name="tbj" FontSize="20" Tapped="tbj_Tapped"></TextBlock>
        </StackPanel>
    </Grid>
    
</UserControl>

MainPage.xaml.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

namespace Application21
{
    partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void tbs_Tapped(object sender, Windows.UI.Xaml.Input.TappedEventArgs e)
        {
           tbs.Text = wv.Source.ToString();
        }

        private void tbj_Tapped(object sender, Windows.UI.Xaml.Input.TappedEventArgs e)
        {
            var url = wv.InvokeScript("eval", new String[] { "(function(){return location.href})();" });
            tbj.Text = url.ToString();
        }
    }
}