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 else36 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 else12 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 else42 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 else48 {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):万事起头难相关推荐
- 计划测试系列(一)--万事开头难
测试计划应该是整个测试流程中第一份测试文档了,但是一般情况下去不是测试人员学习的第一站.或许是因为万事开头难的缘故,测试 计划确实挺让人纠结了. 很多有了一定的经验的测试人员在教新人的时候第一步都不是 ...
- 万事起头难:完整步骤带你学会Node.js环境配置
1.nodeJs下载地址,这里可以选择你想要的版本,我这里以14.15.1为例 2.下载完成后,直接傻瓜式安装即可. 3.打开命令行(以管理员身份打开),输入node -v,出现以下版本号,代表nod ...
- WPF基础到企业应用系列8——依赖属性之“风云再起”
一. 摘要 首先圣殿骑士很高兴"WPF 基础到企业应用系列" 能得到大家的关注.支持和认可.看到很多朋友留言希望加快速度的问题,我会尽力的,对你们的热情关注也表示由衷的感谢.这段时 ...
- 一起谈.NET技术,WPF 基础到企业应用系列5——WPF千年轮回2
一,摘要 首先很高兴这个系列能得到大家的关注和支持,前端时间身体状况不适,所以暂停了更新,对此表示非常抱歉,以后会逐渐加快进度,不过由于这是一个很长的系列,我也想把它写好,所以以后也会慢慢来,在这个系 ...
- 出于一些原因的考虑,即日起,一步一步SharePoint 2007系列文章将暂停发布
非常抱歉的告诉大家,出于一些原因的考虑,即日起,一步一步SharePoint 2007系列文章将暂停发布,恢复发布的时间大致确定在11月上旬.希望朋友们能原谅! 感谢朋友们的一贯支持! 转载于:htt ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):目录
本系列教程的示例代码下载(感谢 银光中国 提供资源分流): 第一部分源码:WPFGameTutorial_PartI(1-20节) 第二部分源码:WPFGameTutorial_PartII(21-2 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②
第二种方法,CompositionTarget动画,官方描述为:CompositionTarget对象可以根据每个帧回调来创建自定义动画.其实直接点,CompositionTarget创建的动画是基于 ...
- WPF仿网易云音乐系列(一、左侧菜单栏:Expander+RadioButton)
WPF仿网易云音乐系列(一.左侧菜单栏:Expander+RadioButton) 原文:WPF仿网易云音乐系列(一.左侧菜单栏:Expander+RadioButton) 1.简介 上一篇咱们说到, ...
- WPF 基础到企业应用系列2——WPF前世今生
1.开篇前言 很多时候了解一项新技术的历史和趋势往往比这项技术的本身价值还要重要.WPF作为一项新技术(已经三年多了,或者应该叫老技术了),我们都有必要了解它的来龙去脉,尤其是公司的CTO ...
最新文章
- 高效程序员的 7 个共同特征
- 二叉树(构造与遍历方法)
- 【翻译】TCP backlog在Linux中的工作原理
- Unity AOP 处理异常的方法
- php中curl类常用方法封装和详解
- 屏幕坏点检测图片_iPhone新机如何检测质量 iPhone新机检测质量步骤【详解】
- 升级Win11正式版啦!这优化神了,界面不输苹果,速度飞快让人秒弃Win10!
- Centos安装NFS服务器配置及挂载教程
- Mark:Camel SQL Route
- MFC开发IM-第二十篇、MFC添加自定义消息
- maven的setting文件简单配置
- webpack热更新和常见错误处理
- 中铁置业引入USB Server助力RPA机器人
- java adsl 拨号_Java实现ADSL拨号上网
- OpenStack修改Guest用户密码——利用Qemu guest agent实现
- 2021 HTML面试题(最新)不定时更新
- el-table 跨行/跨列 的写法
- ImageView 加载本地(手机)图片
- 游戏音乐的成长经历了哪些?
- C练题笔记之:Leetcode-13. 罗马数字转整数