WPF一步一脚印系列(1):万事起头难-阿里云开发者社区

开发者社区> 开发与运维> 正文

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;

 

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章