我用了
<Grid x:Name="ContentPanel" Grid.Row="1">
<ScrollViewer>
<StackPanel >
<TextBlock x:Name="AH1TextBlock" Text="< Tab This >" Style="{StaticResource BaseTextBlockStyle}" />
<TextBlock x:Name="AH2TextBlock" Text="< Tab this >" Style="{StaticResource OliveTextBlockStyle}" />
<Image x:Name="AH1Image" Style="{StaticResource ImageStyle}" />
<Image x:Name="AH2Image" Style="{StaticResource ImageStyle}" />
<Image x:Name="ContentImage" Style="{StaticResource ImageStyle}" />
<Image x:Name="ResourceImage" Style="{StaticResource ImageStyle}" />
</StackPanel>
</ScrollViewer>
</Grid>
接下來在專案中建立一個 Images 資料夾,在資料夾當中加入改了 Build Action 會有什麼不一樣?
做一下編譯動作後,在 bin 底下的資料夾中會發現有一個 .xap 的檔案,用解壓縮程式解開來後你會發現剛剛我們建的 Images 的資料夾,裡頭有剛剛設成 Content 的那張圖片,另外一張圖片則會轉成 Binary 被包在元件 .dll 當中,如果用 Reflector 工具來看,你就可以看得到那張圖片在裡面。
那要用哪一個 Build Action 比較好?
Charles Petzold eBook 上有提到說在 Creating High Performing Silverlight Applications for Windows Phone 這份文件中有提到,使用 Content 的方式可以降低元件 (Assebmly)的大小(因為不用把圖片嵌入在裡面了),這樣的話可以提昇應用程式開啟的速度。
接下來我們來讓圖片能顯示出來,做法很一般就在 XAML 的控制項上將相對路徑設在 Source 屬性上就能取得圖片資料。
<Image x:Name="ContentImage" Style="{StaticResource ImageStyle}" Source="Images/AnneHathaway3.jpg" />
<Image x:Name="ResourceImage" Style="{StaticResource ImageStyle}" Source="Images/AnneHathaway4.jpg" />
如果需要利用程式動態的設定圖片,可參考下列程式碼,但是不可以指直接將一個字串的路徑設給 Image.Source。ContentImage.Source = new BitmapImage(new Uri("Images/AnneHathaway3.jpg", UriKind.Relative));
如果 BuildActuin 是 Resource 還可利用如下的方式取得圖片資源。StreamResourceInfo resourceInfo = Application.GetResourceStream(new Uri("/AssignImageSource;component/Images/AnneHathaway4.jpg", UriKind.Relative));
var bmp = new BitmapImage();
bmp.SetSource(resourceInfo.Stream);
ResourceImage.Source = bmp;
指定的路徑中 /AssignImageSource 是元件名稱,你可以在方案總管 (Solution Explorer) 點擊專案 >> 屬性 就可以看到元件名稱 (Assembly Name) 的設定輸入方塊, component是一個固定值,指的是目前的元件。如果要指定網路上的圖片資源作法也是一樣。
AH1Image.Source = new BitmapImage(new Uri("http://images.huffingtonpost.com/2010-02-08-500x_anne.jpeg"));
如果檔案大一點需要顯示下載的進度,則可以利用 WebClient 來下載圖片,先在 XAML 增加一個 ProgressBar 用來顯示進度。<ProgressBar x:Name="DownloadProgressBar" />再建立一個 WebClient 並且指定讀取進度改變、讀取完畢的事件,並呼叫非同步讀取的事件 OpenReadAsync。
WebClient wc = new WebClient();
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri("http://www.gaelick.com/wp-content/uploads/2010/02/AnneHathaway.jpg"));
//剛連線時會有連接時間的空隙,暫時先讓 ProgressBar 顯示
DownloadProgressBar.IsIndeterminate = true;
建立進度改變的方法,在事件中指定完成的比率給 ProgressBar,因 Framework 設計不允許不同執行緒存取 UI,所以改變時要用委派的方式讓原本建立 UI 的執行緒來變更。void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Dispatcher.BeginInvoke(() => DownloadProgressBar.Value = e.ProgressPercentage);
}
建立下載完畢的事件,在事件中將取回的資料流設給 BitmapImage。void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
BitmapImage bitImage = new BitmapImage();
bitImage.SetSource(e.Result);
AH2Image.Source = bitImage;
AH2Image.Visibility = Visibility.Visible;
DownloadProgressBar.Visibility = Visibility.Collapsed;
AH2TextBlock.Visibility = Visibility.Collapsed;
}
完畢。參考:
eBook: Programming Windows Phone 7, by Charles Petzold
How to: Create a Custom Indeterminate Progress Bar
Creating High Performing Silverlight Applications for Windows Phone Samples




沒有留言:
張貼留言