今天的任务是完成一个Stopwatch的练习,涉及到的知识点有:
- User Control的设计和使用
- 进度条的使用
- 网格视图
- 动态更改/添加控件
1 User Control的设计和使用
1.1 添加自己的User Control
右击解决方案,选择添加新建项,选择User Control,就得到了一个.xaml文件盒一个.cs文件,下面就开始设计这个自定义控件。
1.2 设计自己的User Control
<UserControl x:Class="Stopwatch.WindowsStopWatch"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
VerticalAlignment="Center">
<StackPanel x:Name="LayoutRoot" Orientation="Horizontal"></StackPanel>
</UserControl>
去掉不必要的所有元素,为了将来放进主界面后能与主界面的风格保持一致。
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
namespace Stopwatch
{
public partial class WindowsStopWatch : UserControl
{
TimeSpan time;
int digitWidth;
public WindowsStopWatch()
{
InitializeComponent();
if (DesignerProperties.IsInDesignTool)
this.LayoutRoot.Children.Add(new TextBlock { Text = "0:00.0"});
}
public int DigitWidth
{
get { return this.digitWidth; }
set
{
this.digitWidth = value;
this.Time = this.time;
}
}
public TimeSpan Time
{
get { return this.time; }
//在set中需要更新每次时间变化的界面
set
{
//更新前先清除原先的内容
this.LayoutRoot.Children.Clear();
//分别解析出分钟,秒,和毫秒
string strMinutes = value.Minutes.ToString();
for (int i = 0; i < strMinutes.Length; i++)
{
AddDigits(strMinutes[i].ToString());
}
this.LayoutRoot.Children.Add(new TextBlock { Text = ":" });
AddDigits((value.Seconds / 10).ToString());
AddDigits((value.Seconds % 10).ToString());
this.LayoutRoot.Children.Add(new TextBlock { Text = "." });
AddDigits((value.Milliseconds / 100).ToString());
this.time = value;
}
}
//向StackPanel中添加数字
public void AddDigits(string digitString)
{
TextBlock tb = new TextBlock { Text = digitString, HorizontalAlignment = System.Windows.HorizontalAlignment.Center };
this.LayoutRoot.Children.Add(tb);
}
}
}
1.3 使用自己的User Control
在主页面的命名空间生命中添加对自身程序的引用(项目名称叫做Stopwatch)
xmlns:local="clr-namespace:Stopwatch"
接下来就可以在代码中使用local域中的控件来使用了。
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<local:WindowsStopWatch />
</Grid>
2 设计主界面
<Grid x:Name="LayoutRoot" Background="Transparent" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="4*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Title -->
<TextBlock Grid.ColumnSpan="2" Text="STOPWATCH" FontFamily="{StaticResource PhoneFontFamilySemiBold}"
FontSize="{StaticResource PhoneFontSizeMedium}"/>
<!--Current lap -->
<TextBlock Grid.Row="1" Grid.ColumnSpan="2" Text="Current Lap" TextAlignment="Right" FontFamily="{StaticResource PhoneFontFamilySemiBold}"
FontSize="{StaticResource PhoneFontSizeMedium}"/>
<!--lap time-->
<local:WindowsStopWatch x:Name="CurrentLapTimeDisplay" Grid.Row="2" Grid.ColumnSpan="2" FontSize="{StaticResource PhoneFontSizeLarge}" HorizontalAlignment="Right"
DigitWidth="18"/>
<!--Progress Bar-->
<ProgressBar x:Name="LapProgressBar" Grid.Row="3" Grid.ColumnSpan="2" IsIndeterminate="False" VerticalAlignment="Top" Foreground="{StaticResource PhoneAccentBrush}" />
<!--Total time-->
<local:WindowsStopWatch x:Name="TotalTimeDisplay" Grid.Row="4" Grid.ColumnSpan="2" FontSize="108" FontFamily="Segoe WP Black" HorizontalAlignment="Center" Foreground="{StaticResource PhoneAccentBrush}"/>
<!--four buttons-->
<Button Name="StartButton" Grid.Row="5" Grid.Column="0" Content="start" Foreground="White" Background="{StaticResource PhoneAccentBrush}" Click="StartButton_Click"/>
<Button Name="StopButton" Grid.Row="5" Grid.Column="0" Content="stop" Foreground="White" Background="{StaticResource PhoneAccentBrush}" Click="StartButton_Click" Visibility="Collapsed"/>
<Button Name="LapButton" Grid.Row="5" Grid.Column="1" Content="lap" Foreground="White" Background="{StaticResource PhoneAccentBrush}" Click="StartButton_Click"/>
<Button Name="ResetButton" Grid.Row="5" Grid.Column="1" Content="reset" Foreground="White" Background="{StaticResource PhoneAccentBrush}" Click="StartButton_Click" Visibility="Collapsed"/>
<!--list of laps-->
<ScrollViewer Grid.Row="6" Grid.ColumnSpan="2" FontSize="{StaticResource PhoneFontSizeLarge}">
<StackPanel x:Name="ListStackPanel" />
</ScrollViewer>
</Grid>
效果是这样的:
、
3 实现动态替换应用栏图标
引入命名空间:
using Microsoft.Phone.Shell;
定义IApplicationBarIconButton对象:
IApplicationBarIconButton LockScreenButton;
使用该对象操作
this.LockScreenButton = this.ApplicationBar.Buttons[0] as IApplicationBarIconButton;
以及
if (this.LockScreenButton.Text == "Unlock")
{
this.LockScreenButton.IconUri = new Uri("/Images/appbar.transport.pause.rest.png", UriKind.Relative);
this.LockScreenButton.Text = "Lock";
}
4 实现时间业务
void timer_Tick(object sender, EventArgs e)
{
//throw new NotImplementedException();
TimeSpan delta = DateTime.UtcNow - this.PreviousTick;
this.PreviousTick += delta;
this.TotalTime += delta;
this.CurrentLapTime += delta;
ShowCurrentTime();
}
public void InsertLapstoList()
{
int lapNumber = this.ListStackPanel.Children.Count + 1;
Grid grid = new Grid();
grid.Children.Add(new TextBlock { Text = "lap " + lapNumber, Margin = new Thickness( 24, 0, 0, 0 ) });
WindowsStopWatch watch = new WindowsStopWatch { Time = this.CurrentLapTime, HorizontalAlignment = System.Windows.HorizontalAlignment.Right, DigitWidth = 18, Margin = new Thickness ( 0, 0, 24, 0 ) };
grid.Children.Add(watch);
this.ListStackPanel.Children.Insert(0, grid);
}
public void ShowCurrentTime()
{
this.TotalTimeDisplay.Time = this.TotalTime;
this.CurrentLapTimeDisplay.Time = this.CurrentLapTime;
this.LapProgressBar.Maximum = this.PreviousLapTime.TotalSeconds;
this.LapProgressBar.Value = this.CurrentLapTime.TotalSeconds;
}