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;

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏学海无涯

iOS开发之XLForm的使用

在iOS开发中,开发"表单"界面,字段稍微多一点的一般都用UITableView来做,而XLForm就是这样一个框架,它是创建动态表格视图最牛逼的iOS库, 用...

47280
来自专栏菩提树下的杨过

如何对动态创建控件进行验证以及在Ajax环境中的使用

首先给一个常规的动态创建控件,并进行验证的代码 [前端aspx代码] <%@ Page Language="C#" AutoEventWireup="true"...

20850
来自专栏葡萄城控件技术团队

VS2010 Extension实践(1)

最近VS2010 Extension在Visual Studio Blog(http://blogs.msdn.com/visualstudio/)上提得很频繁...

21390
来自专栏跟着阿笨一起玩NET

总结DevExpress10个使用技巧

87320
来自专栏游戏杂谈

测试用户的网络环境

这个其实是一个hta文件,目的是测试用户本机请求资源、hosts文件、当前所处的位置。参考stone的checknetwork4qqfarm: http://c...

27510
来自专栏互联网开发者交流社区

窗体应用程序防腾讯QQ源码

21040
来自专栏葡萄城控件技术团队

七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理

系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 ...

34080
来自专栏林德熙的博客

win 10 UWP 标签

本文主要翻译:http://visuallylocated.com/post/2015/02/20/Creating-a-WrapPanel-for-your-...

11320
来自专栏林德熙的博客

WPF 修改图片颜色

在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件。

41810
来自专栏pangguoming

c#以POST方式模拟提交表单

这是我一年前写的一个用C#模拟以POST方式提交表单的代码,现在记录在下面,以免忘记咯。那时候刚学C#~忽忽。。很生疏。。代码看上去也很幼稚 臃肿不堪 #reg...

35890

扫码关注云+社区

领取腾讯云代金券