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 CountingLeader
2 {
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 CountingLeader
2 {
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 VideoPlayer
2 {
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;

 

以上是今天做的练习,十分简单最适合像我这样的初学者了,一步一个脚印坚持不懈!!



posted @ 2011-12-31 16:53  ^_^肥仔John  阅读(601)  评论(0编辑  收藏  举报