一直从事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;
以上是今天做的练习,十分简单最适合像我这样的初学者了,一步一个脚印坚持不懈!!