wp7學習筆記(轉)

wp7學習筆記
Emulator中文叫仿真器,是精確地在一種環境下仿真另一種環境下的運行方式。其目的是完全仿真。Simulator中文叫模擬,是通過某種手段來模擬某些東西,不一定要完全正確的原理,追求的只是儘可能的相像。所以XDE是WP7的Emulator,是一個WP7的虛擬機,我準備寫一個XP下開發WP7程序的Simulator。

1、XBox和WP7之間的遊戲移植很方便。
2、WP7程序不能運行在後臺,不支持多任務。
3、C#是唯一支持的開發語言,不能使用native code,不能PInvoke
4、WP7使用Zune連接電腦,不再支持通過ActiveSync的聯繫人的同步,而是通過網絡同步聯繫人。
5、使用高級Task的時候必須對模擬器進行Unlock,因爲沒有Unlock的話模擬器的內容很少。
6、WP7首頁上的方框叫Tile,
7、一個程序只能有一個Frame,是所有頁面的容器,爲SystemTray和ApplicationBar預留空間
8、顯示的方向通過Orientation屬性來設置:Portrait是豎向,Landscape是橫向;SupportedOrientations屬性設置支持的方向(默認值是Portrait,也就是隻支持豎向。如果設置爲PortraitOrLandscape則在轉向的時候界面會自動調整);當轉向的時候OrientationChanged事件會被觸發。
9、WP7中頁面的跳轉不再是Show這種方式,而是頁面Navigation跳轉,類似於網頁:this.NavigationService.Navigate(new Uri("/Page1.xaml",UriKind.Relative));this.NavigationService.GoBack();this.NavigationService.GoForward();
跳轉的時候還可以填值:this.NavigationService.Navigate(new Uri("/Page1.xaml?name=tome",UriKind.Relative));
頁面中獲取值:this.NavigationContext.QueryString["name"];

可以override OnNavigatedFrom、OnNavigatedTo、OnNavigatingFrom幾個方法進行導航的響應。

在普通SL中執行這個的話需要使用“導航Silverlight”模板,參考:http://www.cnblogs.com/steven_gsj/archive/2010/04/24/1719265.html如果導航失敗的話是設置UriMapper的原因,清空即可。NavigationService在Page中才有。

10、shell:SystemTray.IsVisiable屬性控制SystemTray可見性
11、ApplicationBar就是菜單欄。ApplicationBarIconButton屬性IconUrl、Text,圖標要求是48*48png圖,前景色一般是白色,微軟在C:\Program Files\Microsoft SDKs\Windows Phone\v7.0\Icons中提供了一些常用的圖標.ApplicationBarIconButton最多隻能添加4個,引進圖片的時候一定要注意在VS選擇圖片的屬性“BuildAction=Content”、“如果較新則複製”。MenuItems也是放到ApplicationBar中的,MenuItems沒有圖片、沒有二級菜單。

12、Style="{StaticResource PhoneTextNormalStyle}"引用的是資源。代碼中用Application.Current.Resources["name"]來加載資源。儘量不要使用自己的顏色,而是引用系統資源中定義的顏色,這個和CSS原理類似。默認系統資源在C:\Program Files\Microsoft SDKs\Windows Phone\v7.0\Design\ThemeResources.xaml下

13、獨立存儲(IsolatedStorage)只有本程序可以訪問該區域,安全性高,默認大小爲2GB,不能長期保存數據。位於System.IO.IsolatedStorage命名空間下,solatedStorageFile、solatedStorageFileStream兩個類。
創建IsolatedStorageFile的方法IsolatedStorageFile.GetUserStoreForApplication(),IsolatedStorageFile類有CreateDirectory()、DirectoryExists()等很多有用的方法。
創建讀寫流的方法:IsolatedStorageFileStream stream = new IsolatedStorageFileStream("3.txt", FileMode.OpenOrCreate,
IsolatedStorageFile.GetUserStoreForApplication())

14、在Tile中的圖片是在項目的屬性中修改的。
15、如果採用Grid佈局,相當於ColumnDefinitions和RowDefinitions將界面劃分成了網格,然後元素通過Grid.Column、Grid.Row屬性來設置它顯示在哪個格子中。
16、Canvas佈局中代碼修改元素位置的方法Canvas.SetLeft(img1,30);
17、Popup容器可以將內部的內容放到頂層顯示,IsOpen屬性用來標誌是否顯示。因爲SL中頁面顯示一般是用導航的,但是如果想實現WinForm中對話框的效果就可以用Popup
18、ScrollView包含的內容會可以滾動。
19、HyperlinkButton是一個用於本地、Web的超鏈接。NavigationUri指向地址,如果指向的是Web地址,則必須設定Target屬性。HyperlinkButton可以給Background屬性設定ImageBrush來顯示圖片超鏈接。
20、用模擬器的時候按Pause鍵就可以用電腦鍵盤輸入了。
21、TextBox設定InputScope屬性可以讓軟鍵盤換不同的佈局,設置爲TelephoneNumber會顯示爲數字鍵盤,設置爲Url鍵盤會顯示“.com”按鈕。所有可選值位於InputScopeNameValue這個枚舉中。
22、Image控件只支持png和jpg圖片,可以通過Source屬性顯示本地或者網絡圖像,網絡圖片直接填路徑就行了,不用通過代碼先下載。通過代碼加載this.img1.Source = new BitmapImage(new Uri("Desert.jpg",UriKind.Reltive));this.img1.Source = new BitmapImage(new Uri("http://www.baidu.com/Desert.jpg",UriKind.Absolute));
23、MediaElement能夠播放本地或者網絡上的多媒體,支持WAV、MP3等,支持mms、rtspt、rtsp等流媒體協議。主要屬性:IsMuted,是否靜音;Stretch,填充方式;AutoPlay:自動播放。事件:MediaOpend、MediaEnded、MediaFailed。
24、推薦使用DispatcherTimer來做定時。因爲如果用Timer的話在Timer的Elapsed中訪問UI的話需要同步到UI線程執行,而DispatcherTimer是運行在Dispatcher上的,所以訪問UI的時候不需要委託到UI線程執行。
25、Thumb是一個可拖動的控件,簡化了拖動的開發,Thumb是默認沒有再ToolBox中的,需要ChooseItem選進來。通過DragCompleted、DragDelta、DragStarted事件來響應。
當一個Thumb拖動的時候跟着鼠標走:
<Thumb Height="87" HorizontalAlignment="Left" Margin="89,163,0,0" Name="thumb1" VerticalAlignment="Top" Width="91" DragCompleted="thumb1_DragCompleted" DragDelta="thumb1_DragDelta">
<Thumb.RenderTransform>
<TranslateTransform x:Name="tr"></TranslateTransform>
</Thumb.RenderTransform>
</Thumb>
private void thumb1_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
tr.X = tr.X+e.HorizontalChange;
tr.Y = tr.Y+e.VerticalChange;
}
在Silverlight中一般不直接修改元素的座標、大小,在需要修改元素的座標、大小的時候一般使用Transform來做。
26、ListBox通過ItemTemplate來定製外觀,Template內部用Text="{Binding Text}"進行綁定
綁定的對象的類要是public的,否則會綁定失敗
<ListBox Height="361" HorizontalAlignment="Left" Margin="60,165,0,0" Name="listBox1" VerticalAlignment="Top" Width="311" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="100" Height="100" Source="{Binding Avatar}"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public ImageSource Avatar { get; set; }
}

List<Person> list = new List<Person>();
list.Add(new Person { Name="Tom",Age=20,Avatar=new BitmapImage(new Uri("Images/1.jpg",UriKind.Relative))});
list.Add(new Person { Name = "Jim", Age = 22, Avatar = new BitmapImage(new Uri("Images/2.jpg", UriKind.Relative)) });
listBox1.ItemsSource = list;

圖片的路徑不能以“/”開頭,也就是不能"/Images/1.jpg"。

ImgSource屬性是ImageSource類型,ImageSource的一個子類是BitmapImage
27、InkPresenter可以產生手寫效果。事件:LostMouseCapture、MouseLeftButtonDown、MouseMove。
鼠標畫圖的典型代碼:
private Stroke stroke;
private void inkPresenter1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
inkPresenter1.CaptureMouse();
stroke = new Stroke();
stroke.DrawingAttributes.Color = Colors.Red;
inkPresenter1.Strokes.Add(stroke);
}

private void inkPresenter1_MouseMove(object sender, MouseEventArgs e)
{
stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter1));
}
28、WP7中可以使用BMSL來使用BingMaps
29、微軟發佈了Silverlight控件之外的Silverlight Toolkit,有wp7的版本。提供了額外的控件:AutoCompleteBox、ContextMenu、DatePicker、TimePicker、LongListSelector、ListPicker、ToggleSwitch(很好看的開關)、WrapPanel等控件
1)ContextMenu控件提供了上下文菜單,長按屏幕彈出,因爲手機中沒有右鍵。ContextMenu不能用在容器控件中
<TextBox Height="72" HorizontalAlignment="Left" Margin="17,109,0,0" Name="textBox1" Text="TextBox" VerticalAlignment="Top" Width="384">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="複製"/>
<toolkit:Separator/>
<toolkit:MenuItem>
<toolkit:MenuItem.Header>
<Image Width="30" Height="30" Source="ApplicationIcon.png"/>
</toolkit:MenuItem.Header>
</toolkit:MenuItem>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBox>
ContextMenu還可以設定Margin屬性,這時候Margin屬性用來改變菜單相對於控件的位置。
2)WrapPanel會將放到其中的控件按照從左到右、從上到下的順序依次排列。
3)DatePicker、TimePicker是非常易用的日期、時間選擇器,而且可以通過ValueStringFormat來修改顯示格式,語法就是DateTime.ToString的格式語法。
4)ListPicker和ListBox的不同在於,如果爲FullMode那麼當點擊ListPicker的時候會彈出一個全屏窗口來選擇,用起來更方便。
5)LongListSelector用來對數據進行快速的分類定位,非常方便,用起來比較複雜,看例子就行。

30、Panorama控件是一個全景視圖控件,像一個窗口,能夠查看內容的一部分。全景視圖由Background、Title、Items組成。可以自己加這些控件,也可以用項目嚮導中的“WindowsPhone Panorama Application”快速創建一個完整的Panorama控件項目,用來學習很方便。用法看向導生成的代碼即可。
31、Pivot控件是一個豎向滾動的控件。
32、WP7中可以使用DeepZoom技術。
wp7社區http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series
33、Blend的使用:
1)向左下角傾斜的按鈕是漸變工具,可以設置控件的漸變。漸變有線性漸變、徑向漸變兩種。
2)筆刷變換工具是對控件的Brush進行變形的工具,和控件變形不一樣。
3)轉換(Transform)中的RenderTransfer可以用來實現旋轉、縮放、位移等效果。
4)可以選中一個控件然後再在控件裏添加子控件
5)新建時間線、可以選擇不同的關鍵幀,在關鍵幀處設置控件屬性變化的目標值。
6)可以將Brush等轉換爲資源,這樣可以服用,類似於CSS。可以設置一個畫刷,然後點擊旁邊的小方塊圖標,選擇“轉換爲新資源”,保存的時候可以保存爲UserControl中還是單獨的文件中,類似於在htm中聲明樣式和單獨的css中聲明樣式。一旦轉換爲資源,就可以在“畫筆資源”面板中選擇了。

45、SL控件包含Parts、States Model兩部分,Parts就是子控件。StatesModel包含:Visual States(控件在不同狀態下顯示的效果)、Visual State Groups(爲有互斥效果的控件提供的,相同的Visual State Groups是互斥的,不同的Visual State Groups是不互斥的)、Visual Transition(視覺狀態轉換時切換動畫效果)。
1)快速設置控件的Visual State的方法:繪製Ellipse等圖形,然後點擊右鍵選擇“構成控件(Make Into Control)”,然後選擇要修改的控件即可。假設選擇的是Button控件,這時候編輯器就進入了按鈕的Templates編輯器,這時候設計器中的修改都是反映到Button的Template中的,要想退出需要點擊設計器左上角的“[Button]”,想再次繼續則需要選中按鈕,然後點擊設計器左上角的“Template”,也可以點擊控件,右鍵選擇“編輯模板”→“Editi Current”。
2)如果設置了“構成控件(Make Into Control)”,則默認所有狀態都是一個樣子,點擊按鈕將不會有效果,可以修改不同的狀態的樣子。編輯控件的Template進入Template編輯模式,選擇“狀態(States)”面板中的“Pressed”,調整控件的大小或者顏色,這樣就可以設置按鈕按下的樣式了。
3)除了可以用“構成控件(Make Into Control)”修改控件之外,也可以在控件上點擊右鍵,選擇“編輯模板(Edit Template)”→“編輯副本(Edit Copy)”來修改Template。
4)應用已有樣式模板的方法,點擊控件、右鍵“編輯模板”→“引用資源”
5)控件之間狀態轉換的時候是瞬間切換的,如果想要動畫轉換效果,則需要在狀態上點擊“添加過渡”按鈕添加過渡效果,需要設置過渡時間,注意Normal和Pressed之間一般不能直接轉換,因爲還隔着一個MouseOver呢。
6)可以用自定義Visual State技術來自定義ProgressBar,因爲可以在State內部也是用動畫,這樣就可以實現Indeterminate狀態下一個心臟跳來跳去的效果或者一個星星一閃一閃的效果。

46、WP7沒有提供直接操作SMS、Phone、Email、Camera等的API,需要通過Task來執行,因此無法批量操作、免界面操作。當Task啓動後,自己的應用程序就會被終止,通過Tombstone機制再次喚起自己的程序,並需要維護相關的狀態。
47、Task:
1)PhoneCallTask用來撥號,主要兩個屬性:DisplayName、PhoneNumber,調用Show方法即可啓動。
2)SmsComposeTask用來打開系統SMS程序,並且設置所要發的短信內容和發送人,可以發送彩信,但是隻能發圖片和攝像頭拍照,不能發送聲音和視頻。Body、To兩個屬性。
3)SavePhoneNumberTask用來調用聯繫人程序,將電話號碼保存到選中的聯繫人或者新建聯繫人。屬性:PhoneNumber,事件Completed,無法設置聯繫人的姓名,必須用戶手工填寫。
4)PhoneNumberChooserTask用來打開聯繫人界面,選擇一個聯繫人的號碼。在Completed事件中獲得選擇的號碼。
5)EmailComposeTask用來發郵件。EmailAddressChooserTask用來選擇郵件地址。SaveEmailAddressTask。
6)PhotoChooserTask用來調用圖片程序選擇圖片,並可以進行裁切。ShowCamera用來控制是否顯示拍照程序,PixelWidth、PixelHeight屬性設置裁切的大小,Completed事件用來監聽選擇完成事件。Completed事件中e.ChosenPhoto獲得選中圖像的流。
BitmapImage img = new BitmapImage();
img.SetSource(e.ChosenPhoto);
image1.Source = img;

需要注意PhotoChooserTask不能聲明爲局部變量,必須聲明爲類成員。因爲啓動照相機以後應用就被結束了,因此如果在按鈕Click事件中如下寫:
PhotoChooserTask task = new PhotoChooserTask();
task.Completed += new EventHandler<PhotoResult>(task_Completed);
task.PixelHeight = 100;
task.PixelWidth = 100;
task.ShowCamera = true;
task.Show();

task_Completed事件不會正確觸發的,因爲再次回來已經不是上次引用程序的實例了,因此需要如下編寫:
PhotoChooserTask task = new PhotoChooserTask();
public MainPage()
{
InitializeComponent();
task.Completed += new EventHandler<PhotoResult>(task_Completed);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
task.PixelHeight = 100;
task.PixelWidth = 100;
task.ShowCamera = true;

task.Show();
}
也就是把註冊Completed監聽放到構造函數中,這樣程序重啓啓動以後如果是從照相機返回的事件就會被觸發。
注:這是舊SDK的Bug,新SDK已經沒有這個問題。

7)CameraCaptureTask用於啓動拍照程序,同樣響應Completed事件。
8)MediaPlayerLauncher用來調用系統的MediaPlayer程序播放本地或者Web的媒體。模擬器上無法播放Video。
9)WebBrowserTask用來在瀏覽器中打開URL,只要設定URL屬性即可。
10)SearchTask用來啓動搜索程序,設置SearchQuery屬性。

48、WP7應用程序只支持在前臺執行,如果一個程序在你的程序正在運行的時候啓動,程序收到一個將要被終止的事件通知。在程序關閉狀態下,可以通過WebService來向程序發送信息以及更新程序狀態,這叫PushNotification。
49、Tombstone課執行模式:Tombstoning、PageState、ApplicationState、PersistentData、TransientState。Tombstoning、TransientState下模擬多任務,在Tombstone模式下,應用被操作系統終止,就需要保存TransientState,以便於應用程序復活後恢復應用原狀態。應用程序Lifecycle包括Launching、Running、Closing、Deactivating、Activating這五種運行狀態,在App.xaml.cs中影響這些事件。Deactivating、Activating就是Tombstone下的運行態。通過PhoneApplicationService來保存狀態信息。
可以在Page中override OnNavigatedFrom、OnNavigatedTo方法來保存、恢復狀態。
實現保存文本框中用戶正在輸入的值的代碼:
protected override OnNavigatedFrom(e)
{
PhoneApplicationService.Current.State["Test"] = textbox1.Text;
base.OnNavigatedFrom(e);
}

protected override OnNavigatedTo(e)
{
if(PhoneApplicationService.Current.State.ContainsKey("Test"))
{
textbox1.Text = PhoneApplicationService.Current.State["Test"] as string;
}
base.OnNavigatedTo(e);
}

50、PushNotification的幾個概念:TileNotification可以改變QuickLauchArea內的圖標內容(圖片、文字等)的方式,需要程序被Pin to Start。ToastNotification在屏幕的提示欄中顯示內容,點擊提示欄可以打開應用程序。RawNotification可以用Http方式來接收通知,不可見,以後臺方式傳送通知。WP7上只能有15個PushNotification,如果多個程序都有PushNotification能力,則有的程序可能運行不正常。詳細看視頻。
51、Microsoft.Phone.Info.UserExtendedProperties獲得用戶信息,目前只能獲得一個用於MarketPlace的ANID。DeviceExtendedProperties用來獲取設備信息,可以取道的信息如下:http://msdn.microsoft.com/en-us/library/ff941122(v=vs.92).aspx

52、Microsoft.Devices.Sensors.Accelerometer可以獲取傳感器信息。主要用於遊戲開發。todo:開發一個重力傳感器模擬器。
Accelerometer am = new Accelerometer();
Accelerometer.ReadingChanged+=....;
am.Start();
am.Stop();

53、System.Device.Location命名空間下有獲得定位數據的類。
watcher = new GeoCoordinateWatercher(GeoPositionAccuracy.Default);
watcher.MovementThreshold=35;
watcher.PositionChanged+=....

54、Microsoft.Devices.Radio下的FMRadio類是收音機設備。因爲只有一個收音機,因此是單件模式。todo:作品,帶SNS功能的網絡收音機,能顯示這個頻率的電臺名。能聽友在線交流。
FMRadio radio = FMRadio.Instance;
radio.CurrentRegion = RadioRegion.Europe;
radio.Frequency = 100.5;
radio.PowerMode = RadioPowerMode.On;

55、Microsoft.Devices下的VibrateController可以控制振動器。
VibrateController vc = VibrateController.Default;
vc.Start(TimeSpan.FromMilliseconds(100));//設置震動時間。
vc.Stop()

56、可以用Reactive Extension來實現模擬設備數據(重力、位置等),參考WebCast20101214am_設備開發.zip
57、XNA是基於Managed DirectX的遊戲開發環境。
58、即使不開發遊戲,也可以使用XNA中的一些類。在WP7中使用XNA的時候需要使用定時器定時的執行FrameworkDispatcher.Update()以驅動XNA,否則可能會報錯,一般如下調用:
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(50);
timer.Tick += (sender, e) => { FrameworkDispatcher.Update(); };
timer.Start();

(1)用SoundEffect來播放wav格式的音頻。
SoundEffect sound = new SoundEffect(stream.ToArray(),SampleRate,AudioChannels.Mono);
SoundEffectInstance inst = sound.CreateInstance();
inst.Play();
wav格式文件可以以資源的形式放到程序中。

Windows Phone7或者SL中加載一個資源的方法,以加載wav文件爲例:首先將wav文件的“Build Action”屬性設置爲“Embedded Resource”,假設文件名爲Speech Off.wav放到項目根目錄下:
嵌入資源的名字一般是“Assembly名字.文件夾名.文件名”,如果忘了的話可以用assembly.GetManifestResourceNames()方法獲得所有的資源名。使用string asmName = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Name獲得當前Assembly的名字,不能用Assembly.GetExecutingAssembly().GetName() 方法取,因爲會報錯。
string asmName = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Name;
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(asmName+".Speech Off.wav"))
{
SoundEffect sound = new SoundEffect(ReadFully(stream), 48000, AudioChannels.Mono);
SoundEffectInstance inst = sound.CreateInstance();
inst.Play();
}
public static byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}



(2)Song類播放mp3等格式的音樂,可以播放背景音樂
Song song = Song.FromUri("MyMusic",new Uri("Media/TestMusic.mp3",UriKind.Relative));
MediaPlayer.Play(song);
MediaPlayer類功能非常豐富,提供了播放列表、進度報告、播放狀態事件等,完全可以用來做一個播放器。Song類也提供了獲得專輯、聲道等的方法。
(3)Microphone類(Microsoft.Xna.Framework.Audio)可以調用麥克風錄音,buffer是wav格式的,可以直接傳給SoundEffect播放
Microphone m = Microphone.Default;
m.BufferReady+=...()=>{m.GetData(buffer);};
m.Start();
m.Stop();

private byte[] ReadAllData(Microphone m)
{
List<byte> list = new List<byte>();
byte[] buffer = new byte[1024];
int readlen;
while ((readlen = m.GetData(buffer)) > 0)
{
if (readlen < buffer.Length)
{
list.AddRange(buffer.Take(readlen));
}
else
{
list.AddRange(buffer);
}
}
return list.ToArray();
}
(4)與用戶交互的方法:手勢和觸控。位於Microsoft.Xna.Framework.Input和Microsoft.Xna.Framework.Input.TouchPanel下。
觸控狀態只有Move、Press、Release三種。
TouchCollection touchState = TouchPanel.GetState();
foreach(TouchLocation location in toucheState)
{

}

TouchPanel.GetState()不是阻塞的,因此要在DispatchTimer中不斷的讀取獲取觸控狀態。

手勢的編程:
TouchPanel.EnabledGestures = GestureType.Flick|GestureType.VerticalDrag;//設置程序要監聽的手勢類型。
定時器中不斷的讀取手勢:
if(TouchPanel.EnabledGestures!=GestureType.None&&TouchPanel.IsGestureAvailable)//只有IsGestureAvailable=true才能ReadGesture
GestureType t = TouchPanel.ReadGesture().GestureType;

59、Properties下的WMAppManifest.xml中的Capabilities節點下定義的是程序要求的訪問權限,應該保持權限最小。DefaultTask定義的是啓動頁面。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章