Windows Phone and ProgressBar Using Thread/Multiple Thread (Silverlight) |
Windows Phone and ProgressBar Using Thread/Multiple Thread (Silverlight) ตัวอย่างการเขียน App บน Windows Phone กับการสร้าง ProgressBar ภายใต้การทำงานของ Thread โดยบทความนี้จะได้เข้าใจโครงสร้างพื้นฐานการเขียนโปรแกรมบน .NET กับ Windows Phone ในการสร้าง ProgressBar ที่ทำงานร่วมกับ Thread รวมทั้งการทำงานแบบ Mutiple Thread และการ Update Status ไปยังหน้าจอของ Page ในขณะที่ Thread กำลังทำงาน รวมถึงการแจ้งสถานะเป็น 1-100 % ทาง TextBlock
Windows Phone and ProgressBar Using Thread/Multiple Thread
Windows Phone and Thread (Silverlight)
สำหรับการทำงานของ Thread ควรอ่านบทความนี้เพื่อความเข้าใจ
Example 1 ตัวอย่างการใช้ Thread กับ ProgressBar แบบง่าย ๆ
ออกแบบ Layout เหมือนในภาพ
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Button Content="Start" Height="72" HorizontalAlignment="Left" Margin="148,89,0,0" Name="btnStartThread" VerticalAlignment="Top" Width="160" Click="btnStartThread_Click" />
<ProgressBar Height="4" HorizontalAlignment="Left" Margin="-1,245,0,0" Name="ProgressBar1" VerticalAlignment="Top" Width="460" />
<TextBlock Height="30" HorizontalAlignment="Right" Margin="0,293,12,0" Name="txtResult" Text="Result" VerticalAlignment="Top" Width="438" TextAlignment="Center" />
</Grid>
</Grid>
VB.NET
Private Sub btnStartThread_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
btnStartThread.IsEnabled = False
Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf ThreadStart)
thread.Start()
End Sub
Private Sub ThreadStart()
Dim intProgress As Integer = 0
'*** for Display ***'
Dim display As New Action(Of Integer)(AddressOf UpdateStatus)
'*** when Finish ***'
Dim finish As New Action(AddressOf UpdateFinish)
'*** Example for Execute
For i As Integer = 0 To 100
intProgress = i
System.Threading.Thread.Sleep(100)
Dispatcher.BeginInvoke(display, intProgress) 'Update Status
Next
Dispatcher.BeginInvoke(finish) ' When Finish
End Sub
'*** for Update Status
Private Sub UpdateStatus(ByVal intProgress As Integer)
'*** Update Progress ***'
Me.ProgressBar1.Value = intProgress
'*** Update Text Result ***'
Me.txtResult.Text = intProgress & " %"
End Sub
'*** for When Thread Complete
Private Sub UpdateFinish()
btnStartThread.IsEnabled = True
End Sub
C#
private void btnStartThread_Click(System.Object sender, System.Windows.RoutedEventArgs e)
{
btnStartThread.IsEnabled = false;
System.Threading.Thread thread = new System.Threading.Thread(ThreadStart);
thread.Start();
}
private void ThreadStart()
{
int intProgress = 0;
//*** for Display ***'
Action<int> display = new Action<int>(UpdateStatus);
//*** when Finish ***'
Action finish = new Action(UpdateFinish);
//*** Example for Execute
for (int i = 0; i <= 100; i++)
{
intProgress = i;
System.Threading.Thread.Sleep(100);
Dispatcher.BeginInvoke(display, intProgress);
//Update Status
}
Dispatcher.BeginInvoke(finish);
// When Finish
}
//*** for Update Status
private void UpdateStatus(int intProgress)
{
//*** Update Progress ***'
this.ProgressBar1.Value = intProgress;
//*** Update Text Result ***'
this.txtResult.Text = intProgress + " %";
}
//*** for When Thread Complete
private void UpdateFinish()
{
btnStartThread.IsEnabled = true;
}
จากตัวอย่าง Code ของ VB.NET และ C# จะยกตัวอย่างการ Loop ข้อมูลจาก 0-100
For i As Integer = 0 To 100
intProgress = i
System.Threading.Thread.Sleep(100)
Dispatcher.BeginInvoke(display, intProgress) 'Update Status
Next
และแต่ล่ะ Loop ก็จะส่งสถานะไป Update ที่ ProgressBar แต่ในหลักการใช้งานจริง ๆ อาจจะต้องคำนวณจาก Progress ที่มีอยู่จริง เช่นต้องการ Loop Insert ข้อมูล 1000 รายการ ก็จะใช้การเขียนสูตรว่า 1000/100 = 10 นั่นหมายความว่าทุก ๆ 10 รอบ จะต้องส่ง Status ไป Update ยัง ProgressBar เพื่อจะให้ ProgressBar แสดง Status = 1- 100 หรือในกรณีที่เป็นการดาวน์โหลดไฟล์จาก Server ก็จะต้องหา Size ขนาดของไฟล์ และคำนวณด้วยอัตราส่วน 100 ซึ่งทุก ๆ ครั้งที่มีการดาวน์โหลดไฟล์มาจัดเก็บไว้ในเครื่อง ก็จะต้องส่ง Status ไป Update บน ProgressBar ทุกครั้ง และในส่วนของ System.Threading.Thread.Sleep(100) อาจจะไม่จำเป็นต้องใช้ เพราะจะได้ระยะเวลาใช้งานจริง มาแสดงผลอยู่แล้ว
Screenshot ทดสอบการทำงานบน Emulator ของ Windows Phone
คลิกที่ปุ่ม Start
แสดง ProgressBar และตัวเลขสถานะ ในขณะที่กำลังทำงาน
เมื่อทำงานเสร็จสิ้นก็สถานะจะวิ่งไปจนถึง 100%
Example 2 การใช้ Multiple Thread และ Mutiple ProgressBar แสดง ProgressBar ของแต่ล่ะ Thread
ออกแบบ Layout ดังรูป
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<Button Content="Start" Height="72" Name="btnStartThread" Width="160" Click="btnStartThread_Click" />
</StackPanel>
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
</StackPanel>
</Grid>
VB.NET
Private Sub btnStartThread_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf ThreadStart)
thread.Start()
End Sub
Private Sub ThreadStart()
Dim intProgress As Integer = 0
Dim threadID As String = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()
'*** for Begin create Control ***'
Dim begin As New Action(Of String)(AddressOf BeginCreate)
'*** for Display ***'
Dim display As New Action(Of Integer, String)(AddressOf UpdateStatus)
'*** when Finish ***'
Dim finish As New Action(AddressOf UpdateFinish)
Dispatcher.BeginInvoke(begin, threadID) ' Create ProgressBar
'*** Example for Execute
For i As Integer = 0 To 100
intProgress = i
System.Threading.Thread.Sleep(100)
Dispatcher.BeginInvoke(display, intProgress, threadID) 'Update Status
Next
Dispatcher.BeginInvoke(finish) ' When Finish
End Sub
'*** for Create control ProgressBar
Private Sub BeginCreate(ByVal threadID As String)
Dim ctrlProgress As New ProgressBar
ctrlProgress.Name = "Progress" & threadID
ContentPanel.Children.Add(ctrlProgress)
Dim ctrlText As New TextBlock
ctrlText.Name = "text" & threadID
ContentPanel.Children.Add(ctrlText)
End Sub
'*** for Update Status
Private Sub UpdateStatus(ByVal intProgress As Integer, ByVal threadID As String)
'*** Update Progress ***'
Dim progress As ProgressBar = Me.FindName("Progress" & threadID)
progress.Value = intProgress
'*** Update Text Result ***'
Dim text As TextBlock = Me.FindName("text" & threadID)
text.Text = intProgress.ToString() & " %"
End Sub
'*** for When Thread Complete
Private Sub UpdateFinish()
btnStartThread.IsEnabled = True
End Sub
C#
private void btnStartThread_Click(System.Object sender, System.Windows.RoutedEventArgs e)
{
System.Threading.Thread thread = new System.Threading.Thread(ThreadStart);
thread.Start();
}
private void ThreadStart()
{
int intProgress = 0;
string threadID = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
//*** for Begin create Control ***'
Action<string> begin = new Action<string>(BeginCreate);
//*** for Display ***'
Action<int, string> display = new Action<int, string>(UpdateStatus);
//*** when Finish ***'
Action finish = new Action(UpdateFinish);
Dispatcher.BeginInvoke(begin, threadID);
// Create ProgressBar
//*** Example for Execute
for (int i = 0; i <= 100; i++)
{
intProgress = i;
System.Threading.Thread.Sleep(100);
Dispatcher.BeginInvoke(display, intProgress, threadID);
//Update Status
}
Dispatcher.BeginInvoke(finish);
// When Finish
}
//*** for Create control ProgressBar
private void BeginCreate(string threadID)
{
ProgressBar ctrlProgress = new ProgressBar();
ctrlProgress.Name = "Progress" + threadID;
ContentPanel.Children.Add(ctrlProgress);
TextBlock ctrlText = new TextBlock();
ctrlText.Name = "text" + threadID;
ContentPanel.Children.Add(ctrlText);
}
//*** for Update Status
private void UpdateStatus(int intProgress, string threadID)
{
//*** Update Progress ***'
ProgressBar progress = (ProgressBar)this.FindName("Progress" + threadID);
progress.Value = intProgress;
//*** Update Text Result ***'
TextBlock text = (TextBlock)this.FindName("text" + threadID);
text.Text = intProgress.ToString() + " %";
}
//*** for When Thread Complete
private void UpdateFinish()
{
btnStartThread.IsEnabled = true;
}
จาก Code ของ .NET จะมีการเพิ่ม Control ลงใน StackPanel ชื่อว่า ContentPanel
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
</StackPanel>
StackPanel บน XAML
private void BeginCreate(string threadID)
{
ProgressBar ctrlProgress = new ProgressBar();
ctrlProgress.Name = "Progress" + threadID;
ContentPanel.Children.Add(ctrlProgress);
TextBlock ctrlText = new TextBlock();
ctrlText.Name = "text" + threadID;
ContentPanel.Children.Add(ctrlText);
}
Create Control ลงบน ContentPanel ซึ่งจะได้ ProgressBar ตามจำนวนของ Thread
Screenshot ทดสอบการทำงานบน Emulator ของ Windows Phone
คลิกที่ Start หลาย ๆ ครั้งเพื่อสั่งให้ทำงาน Mutiple Thread โดยคลิกในระยะเวลาใกล้เคียงกัน
จะเห็นว่าจำนวน ProgressBar จะสร้างเท่ากับจำนวนของ Thread และจะแสดง ProgressBar รวทั้งจำนวนตัวเลขแจ้งสถานะของแต่ล่ะ Thread ด้วย
แสดง ProgressBar ครบ 100% เมื่อ Thread ทำงานจนเสร็จสิ้น
.
|
ช่วยกันสนับสนุนรักษาเว็บไซต์ความรู้แห่งนี้ไว้ด้วยการสนับสนุน Source Code 2.0 ของทีมงานไทยครีเอท
|
|
|
By : |
ThaiCreate.Com Team (บทความเป็นลิขสิทธิ์ของเว็บไทยครีเอทห้ามนำเผยแพร่ ณ เว็บไซต์อื่น ๆ) |
|
Score Rating : |
|
|
|
Create/Update Date : |
2012-09-05 21:54:03 /
2017-03-25 21:55:26 |
|
Download : |
|
|
Sponsored Links / Related |
|
|
|
|
|
|
|