WPF一步一脚印系列(1):万事起头难
? 一直從事Asp.Net的開發,而C/S的開發方面簡直是一片空白,于是從上星期開始就痛下決心開始學習WPF。我采取的策略是網上看基礎資料+做簡單的demo練習+網上查資料。從csdn上下了個比較不錯的基礎講解文檔,花了幾天時間終于把它看完,算是有個基本了解吧,今天開始寫些小練習。
? 這個系列主要是用來記錄自己學習WPF的心路歷程,以實例為主配合原理和注意點的說明,有紕漏之處請大家多多指正!!^_^
實例1——倒計算器 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
最終效果:
Window1.xaml:
1 <Window x:Class="CountingLeader.Window1"2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="300" Width="300">
5 <Grid>
6 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
7 <StackPanel.Resources>
8 <Style TargetType="TextBlock">
9 <Setter Property="FontSize" Value="50"></Setter>
10 </Style>
11 </StackPanel.Resources>
12 <TextBlock x:Name="tbkHour" Text="00"></TextBlock>
13 <TextBlock Text=":"></TextBlock>
14 <TextBlock x:Name="tbkMinute" Text="10"></TextBlock>
15 <TextBlock Text=":"></TextBlock>
16 <TextBlock x:Name="tbkSecond" Text="45"></TextBlock>
17 </StackPanel>
18 </Grid>
19 </Window>
Window1.xaml.cs:
1 namespace CountingLeader2 {
3 /// <summary>
4 /// Window1.xaml 的交互邏輯
5 /// </summary>
6 public partial class Window1 : Window
7 {
8 private CountingLeaderManager clm = null;
9
10 public Window1()
11 {
12 InitializeComponent();
13
14 this.Loaded += new RoutedEventHandler(Window_OnLoaded);
15 clm = new CountingLeaderManager();
16 }
17
18 public void Window_OnLoaded(object sender, RoutedEventArgs e)
19 {
20 clm.TotalCount = Convert.ToInt32(this.tbkHour.Text) * 3600 +
21 Convert.ToInt32(this.tbkMinute.Text) * 60 +
22 Convert.ToInt32(this.tbkSecond.Text);
23
24 DispatcherTimer timer = new DispatcherTimer();
25 timer.Interval = new TimeSpan(0,0,1);
26 timer.Tick += (ss, ee) =>
27 {
28 if (clm.CanReduce())
29 {
30 clm.Reduce();
31 this.tbkHour.Text = clm.GetHour();
32 this.tbkMinute.Text = clm.GetMinute();
33 this.tbkSecond.Text = clm.GetSecond();
34 }
35 else
36 timer.Stop();
37 };
38 timer.Start();
39 }
40 }
41 }
CountingLeader.cs:
1 namespace CountingLeader2 {
3 public class CountingLeaderManager
4 {
5 public int TotalCount { get; set; }
6
7 public bool CanReduce()
8 {
9 if (TotalCount == 0)
10 return false;
11 else
12 return true;
13 }
14
15 public int Reduce()
16 {
17 return --TotalCount;
18 }
19
20 public string GetHour()
21 {
22 return GetCount(() => TotalCount / 3600 );
23 }
24
25 public string GetMinute()
26 {
27 return GetCount(() => TotalCount % 3600 / 60);
28 }
29
30 public string GetSecond()
31 {
32 return GetCount(() => TotalCount % 60);
33 }
34
35 private string GetCount(Func<int> func)
36 {
37 string result = string.Empty;
38 int resultInt = func();
39 if (resultInt <= 9)
40 result = "0" + resultInt;
41 else
42 result = resultInt.ToString();
43
44 return result;
45 }
46 }
47 }
wf時期的有三種計時器供大家使用:System.Threading.Timer、System.Timers.Timer和System.Windows.Forms.Timer,如果計時器用在UI上那么就使用System.Timers.Timer,因為它由UI線程實現;如果實現與UI無關的操作可以用System.Threading.Timer,它是從系統的線程池中取線程實現計時器的功能,但因不是用UI線程實現而無法操作UI上的控件;而System.Timers.Timer是由服務器實現,具體有待研究。
而該練習使用的計時器是System.Windows.Threading.DispatcherTimer,.net frameword 3.0后提供,感覺像是wf中的System.Windows.Forms.Timer。
注意:由UI線程實現的計時器會阻塞UI的交互操作。
1 timer.Tick += (ss, ee) =>2 {
3 System.Threading.Thread.Sleep(100000);
4 };
將Window1.xaml.cs文件中的timer.Tick部分修改為上述代碼后,明顯看到計時器跟UI交互操作使用的同一個線程。
實例2:簡易多媒體播放器 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
最終效果:
?
Window1.xaml:
?
1 <Window x:Class="VideoPlayer.Window1"2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="300" Width="300">
5 <StackPanel>
6 <Border Background="Gray">
7 <Border.BorderBrush>
8 <SolidColorBrush Color="Silver"></SolidColorBrush>
9 </Border.BorderBrush>
10 <MediaElement x:Name="me" LoadedBehavior="Manual" MinHeight="200"
11 Volume="{Binding ElementName=volumeSlider,Path=Value}"></MediaElement>
12 </Border>
13 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
14 <StackPanel.Resources>
15 <Style TargetType="Button">
16 <Setter Property="Background">
17 <Setter.Value>
18 <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
19 <LinearGradientBrush.GradientStops>
20 <GradientStopCollection>
21 <GradientStop Color="White" Offset="0.1"></GradientStop>
22 <GradientStop Color="#232323" Offset="1"></GradientStop>
23 </GradientStopCollection>
24 </LinearGradientBrush.GradientStops>
25 </LinearGradientBrush>
26 </Setter.Value>
27 </Setter>
28 <Setter Property="Margin" Value="2"></Setter>
29 <Setter Property="FontStyle" Value="Italic"></Setter>
30 <Style.Triggers>
31 <Trigger Property="IsMouseOver" Value="true">
32 <Setter Property="Foreground" Value="Gold"></Setter>
33 </Trigger>
34 <Trigger Property="IsEnabled" Value="false">
35 <Setter Property="Foreground" Value="Gray"></Setter>
36 </Trigger>
37 </Style.Triggers>
38 </Style>
39 </StackPanel.Resources>
40 <Button x:Name="btnOpenFile" Content="Open File" Click="btnOpenFile_Click"></Button>
41 <Button x:Name="btnPlayOrPause" Content="Play" Click="btnPlayOrPause_Click" IsEnabled="False"></Button>
42 <Button x:Name="btnStop" Content="Stop" Click="btnStop_Click" IsEnabled="False"></Button>
43 <Button x:Name="btnBack" Content="Back" Click="btnBack_Click" IsEnabled="False"></Button>
44 <Button x:Name="btnForward" Content="Forward" Click="btnForward_Click" IsEnabled="False"></Button>
45 </StackPanel>
46 <StackPanel Orientation="Horizontal">
47 <TextBlock Text="Volume:"></TextBlock>
48 <Slider x:Name="volumeSlider" Maximum="1" Minimum="0" Value="0.5" Width="200" ></Slider>
49 </StackPanel>
50 </StackPanel>
51 </Window>
說明:
1.MediaElement的Volume(聲音)是依賴屬性可以使用Slider作為數據源將Slider的Value值綁定到MediaElement;
2.Style中Trigger用來設置按鈕的不可用、鼠標在上面時樣式的變化。
Window1.xaml.cs:
?
1 namespace VideoPlayer2 {
3 /// <summary>
4 /// Window1.xaml 的交互邏輯
5 /// </summary>
6 public partial class Window1 : Window
7 {
8 private bool IsPlaying = false;
9
10 public Window1()
11 {
12 InitializeComponent();
13 }
14
15 private void btnOpenFile_Click(object sender, RoutedEventArgs e)
16 {
17 OpenFileDialog ofd = new OpenFileDialog();
18 ofd.Filter = "mp3文件(*.mp3)|*.mp3|wmv文件(*.wmv)|*.wmv|avi文件(*.avi)|*.avi";
19 if(ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK)
20 {
21 this.me.Source = new Uri(ofd.FileName, UriKind.Absolute);
22 this.btnForward.IsEnabled = true;
23 this.btnBack.IsEnabled = true;
24 this.btnPlayOrPause.IsEnabled = true;
25 this.btnStop.IsEnabled = true;
26 }
27 }
28
29 private void btnForward_Click(object sender, RoutedEventArgs e)
30 {
31 this.me.Position += TimeSpan.FromSeconds(10);
32 }
33
34 private void btnBack_Click(object sender, RoutedEventArgs e)
35 {
36 this.me.Position -= TimeSpan.FromSeconds(10);
37 }
38
39 private void btnPlayOrPause_Click(object sender, RoutedEventArgs e)
40 {
41 if (IsPlaying)
42 {
43 this.me.Pause();
44 (sender as System.Windows.Controls.Button).Content = "Play";
45 IsPlaying = false;
46 }
47 else
48 {
49 this.me.Play();
50 (sender as System.Windows.Controls.Button).Content = "Pause";
51 IsPlaying = true;
52 }
53 }
54
55 private void btnStop_Click(object sender, RoutedEventArgs e)
56 {
57 this.btnPlayOrPause.Content = "Play";
58 this.me.Stop();
59 IsPlaying = false;
60 }
61 }
62 }
說明:
1.這里使用了System.Windows.Forms.OpenFileDialog控件,如果針對Window7開發可以使用WindowsAPICodePack;
?
以上是今天做的練習,十分簡單最適合像我這樣的初學者了,一步一個腳印堅持不懈!!
總結
以上是生活随笔為你收集整理的WPF一步一脚印系列(1):万事起头难的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vnc连接linux时出现黑屏
- 下一篇: NDK开发调试真难