WPF一步一脚印系列(1):万事起头难

简介:

一直从事Asp.Net的开发,而C/S的开发方面简直是一片空白,于是从上星期开始就痛下决心开始学习WPF。我采取的策略是网上看基础资料+做 简单的demo练习+网上查资料。从csdn上下了个比较不错的基础讲解文档,花了几天时间终于把它看完,算是有个基本了解吧,今天开始写些小练习。

  这个系列主要是用来记录自己学习WPF的心路历程,以实例为主配合原理和注意点的说明,有纰漏之处请大家多多指正!!^_^

实 例1——倒计算器                                 


最终效果:

Window1.xaml:

<Window x:Class="CountingLeader.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <StackPanel.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="50"></Setter>
                </Style>
            </StackPanel.Resources>
            <TextBlock x:Name="tbkHour" Text="00"></TextBlock>
            <TextBlock Text=":"></TextBlock>
            <TextBlock x:Name="tbkMinute" Text="10"></TextBlock>
            <TextBlock Text=":"></TextBlock>
            <TextBlock x:Name="tbkSecond" Text="45"></TextBlock>
        </StackPanel>
    </Grid>
</Window>
Window1.xaml.cs:
namespace CountingLeader
{
    /// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
    public partial class Window1 : Window
    {
        private CountingLeaderManager clm = null;

        public Window1()
        {
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(Window_OnLoaded);
            clm = new CountingLeaderManager();
        }

        public void Window_OnLoaded(object sender, RoutedEventArgs e)
        {
            clm.TotalCount = Convert.ToInt32(this.tbkHour.Text) * 3600 +
                Convert.ToInt32(this.tbkMinute.Text) * 60 +
                Convert.ToInt32(this.tbkSecond.Text);

            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0,0,1);
            timer.Tick += (ss, ee) =>
                {
                    if (clm.CanReduce())
                    {
                        clm.Reduce();
                        this.tbkHour.Text = clm.GetHour();
                        this.tbkMinute.Text = clm.GetMinute();
                        this.tbkSecond.Text = clm.GetSecond();
                    }
                    else
                        timer.Stop();
                };
            timer.Start();
        }
    }
}

CountingLeader.cs:
namespace CountingLeader
{
    public class CountingLeaderManager
    {
        public int TotalCount { get; set; }

        public bool CanReduce()
        {
            if (TotalCount == 0)
                return false;
            else
                return true;
        }

        public int Reduce()
        {
            return --TotalCount;
        }

        public string GetHour()
        {
            return GetCount(() => TotalCount / 3600 );
        }

        public string GetMinute()
        {
            return GetCount(() => TotalCount % 3600 / 60);
        }

        public string GetSecond()
        {
            return GetCount(() => TotalCount % 60);
        }

        private string GetCount(Func<int> func)
        {
            string result = string.Empty;
            int resultInt = func();
            if (resultInt <= 9)
                result = "0" + resultInt;
            else
                result = resultInt.ToString();

            return result;
        }
    }
}

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:

 

<Window x:Class="VideoPlayer.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Border Background="Gray">
            <Border.BorderBrush>
                <SolidColorBrush Color="Silver"></SolidColorBrush>
            </Border.BorderBrush>
            <MediaElement x:Name="me" LoadedBehavior="Manual" MinHeight="200"
                          Volume="{Binding ElementName=volumeSlider,Path=Value}"></MediaElement>
        </Border>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <StackPanel.Resources>
                <Style TargetType="Button">
                    <Setter Property="Background">
                        <Setter.Value>
                            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                                <LinearGradientBrush.GradientStops>
                                    <GradientStopCollection>
                                        <GradientStop Color="White" Offset="0.1"></GradientStop>
                                        <GradientStop Color="#232323" Offset="1"></GradientStop>
                                    </GradientStopCollection>
                                </LinearGradientBrush.GradientStops>
                            </LinearGradientBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Margin" Value="2"></Setter>
                    <Setter Property="FontStyle" Value="Italic"></Setter>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Foreground" Value="Gold"></Setter>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="Gray"></Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </StackPanel.Resources>
            <Button x:Name="btnOpenFile" Content="Open File" Click="btnOpenFile_Click"></Button>
            <Button x:Name="btnPlayOrPause" Content="Play" Click="btnPlayOrPause_Click" IsEnabled="False"></Button>
            <Button x:Name="btnStop" Content="Stop" Click="btnStop_Click" IsEnabled="False"></Button>
            <Button x:Name="btnBack" Content="Back" Click="btnBack_Click" IsEnabled="False"></Button>
            <Button x:Name="btnForward" Content="Forward" Click="btnForward_Click" IsEnabled="False"></Button>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Volume:"></TextBlock>
            <Slider x:Name="volumeSlider" Maximum="1" Minimum="0" Value="0.5" Width="200" ></Slider>
        </StackPanel>
    </StackPanel>
</Window>

说明:

1.MediaElement的Volume(声音)是依赖属性可以使用Slider作为数据源将Slider的Value值绑定到MediaElement;

2.Style中Trigger用来设置按钮的不可用、鼠标在上面时样式的变化。

Window1.xaml.cs:

 

namespace VideoPlayer
{
    /// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
    public partial class Window1 : Window
    {
        private bool IsPlaying = false;

        public Window1()
        {
            InitializeComponent();
        }

        private void btnOpenFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "mp3文件(*.mp3)|*.mp3|wmv文件(*.wmv)|*.wmv|avi文件(*.avi)|*.avi";
            if(ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK)
            {
                this.me.Source = new Uri(ofd.FileName, UriKind.Absolute);
                this.btnForward.IsEnabled = true;
                this.btnBack.IsEnabled = true;
                this.btnPlayOrPause.IsEnabled = true;
                this.btnStop.IsEnabled = true;
            }
        }

        private void btnForward_Click(object sender, RoutedEventArgs e)
        {
            this.me.Position += TimeSpan.FromSeconds(10);            
        }

        private void btnBack_Click(object sender, RoutedEventArgs e)
        {
            this.me.Position -= TimeSpan.FromSeconds(10);
        }

        private void btnPlayOrPause_Click(object sender, RoutedEventArgs e)
        {
            if (IsPlaying)
            {
                this.me.Pause();
                (sender as System.Windows.Controls.Button).Content = "Play";
                IsPlaying = false;
            }
            else
            {
                this.me.Play();
                (sender as System.Windows.Controls.Button).Content = "Pause";
                IsPlaying = true;
            }
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            this.btnPlayOrPause.Content = "Play";
            this.me.Stop();
            IsPlaying = false;
        }
    }
}

说明:

1.这里使用了System.Windows.Forms.OpenFileDialog控件,如果针对Window7开发可以使用WindowsAPICodePack;

 

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

目录
相关文章
WPF-ComplexLayout
WPF-ComplexLayout-DockPanel
236 0
WPF-ComplexLayout
|
C# Windows
WPF WriteableBitmap的使用
选中项目按右键添加-资源文件-WPF-窗口generate_bitmap.xml文件内容为
2086 0
|
数据可视化 C#
WPF 中的 NameScope
原文:WPF 中的 NameScope 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:http://blog.csdn.net/wpwalter/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
972 0
|
C# 图形学 数据格式
WPF中的3D Wireframe
原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能。
1289 0
|
数据建模 C#
WPF InkCanvas 毛笔效果
原文:WPF InkCanvas 毛笔效果 1、先来看看InkCanvas的一般用法:                                                                                 2、自定义InkCanvas,实现毛笔效果...
1192 0
|
C# 前端开发
WPF 小技巧
原文:WPF 小技巧 在使用mvvm模式开发时,对于Command的绑定是一件很伤脑筋的事情,尽管有强大的Blend类库支持: xmlns:Custom="http://www.galasoft.ch/mvvmlight"xmlns:i="http://schemas.
748 0
|
C#
使用WPF实现3D场景[二]
原文:使用WPF实现3D场景[二] 在上一篇的文章里我们知道如何构造一个简单的三维场景,这次的课程我将和大家一起来研究如何用代码,完成对建立好了的三维场景的观察。
1078 0
|
C#
使用WPF实现3D场景[一]
原文:使用WPF实现3D场景[一] 在这篇文章里,将介绍如何实现一个简单的三维场景,一个三维的空间,包括空间内的三维物体的组合. 首先介绍一下一个三维场景里的基本元素: 先是定义一个简单的三维的场景环境 代码如下: 以上是定义了一个名称叫做 myViewport 的的三维场景,接下来可以在这个三位场景里添加一些元素: 元素一:照相机 照相机是三维场景内用户的视角,当然照相机也是唯一的。
1503 0
|
C#
浅谈WPF中的PreviewTextInput
原文:浅谈WPF中的PreviewTextInput     今天在使用TextBox的TextInput事件的时候,发现无论如何都不能触发该事件,然后百思不得其解,最后在MSDN上找到了答案:TextInput 事件可能已被标记为由复合控件的内部实现进行处理。
1132 0