在开发过程中,有时候需要自己定义拨号键盘,比如拨号软件,一般还要给键盘添加一些手势操作,比如向上滑动,键盘就上拉显示出来,向下滑动,键盘就向下拉
下面演示一下如何做
1、首先定义一个Grid来存放整个T9拨号键盘,为了让该控件支持手势功能,需要引用 Microsoft.Phone.Controls.Toolkit
添加命名空间的引用
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
添加两个页面资源
<phone:PhoneApplicationPage.Resources>
<Style x:Name="borderclick" TargetType="Border" >
<Setter Property="Background" Value="{StaticResource PhoneAccentBrush}" />
<Setter Property="Margin" Value="2,2,2,2" />
</Style>
<Style x:Name="bordernormal" TargetType="Border" >
<Setter Property="Background" Value="#FF403D49" />
<Setter Property="Margin" Value="2,2,2,2" />
</Style>
</phone:PhoneApplicationPage.Resources>
定义拨号键盘
<Grid Name="gridSearchPanel" Height="450" Margin="0,160,0,0" VerticalAlignment="Top" Background="#FF222223" >
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DragStarted="OnGestureListenerDragStarted"
DragDelta="OnGestureListenerDragDelta"
DragCompleted="OnGestureListenerDragCompleted"
Flick="OnGestureListenerFlick" />
</toolkit:GestureService.GestureListener>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.ColumnSpan="3" Tag="Title" Tap="Border_Tap" Background="#FF222223" >
<TextBlock Name="tbSearch" Margin="12,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="1" Grid.Column="0" Tag="1" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="1" Grid.Column="1" Tag="2" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White"/>
</Border>
<Border Grid.Row="1" Grid.Column="2" Tag="3" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="3" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="2" Grid.Column="0" Tag="4" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="4" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="2" Grid.Column="1" Tag="5" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="5" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="2" Grid.Column="2" Tag="6" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="6" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="3" Grid.Column="0" Tag="7" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="7" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="3" Grid.Column="1" Tag="8" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="8" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="3" Grid.Column="2" Tag="9" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="9" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="4" Grid.Column="0" Tag="*" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="clear" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Foreground="White" />
</Border>
<Border Grid.Row="4" Grid.Column="1" Tag="0" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50" Foreground="White" />
</Border>
<Border Grid.Row="4" Grid.Column="2" Tag="#" Style="{StaticResource bordernormal}" MouseLeave="Border_MouseLeave" MouseLeftButtonDown="Border_MouseLeftButtonDown" Tap="Border_Tap" >
<TextBlock Text="back" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Foreground="White" />
</Border>
</Grid>
2、定义事件函数
首先定义几个辅助变量
Thickness show = new Thickness(0, 160, 0, 0);
Thickness hide = new Thickness(0, 550, 0, 0);
Point pointOrigin;
Thickness marginorigin;
bool isshow;
DateTime timestart;
鼠标点击事件,改变键盘的背景
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Border border = sender as Border;
border.Style = this.Resources["borderclick"] as Style;
}
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
Border border = sender as Border;
border.Style = this.Resources["bordernormal"] as Style;
}
Tap事件
private void Border_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Border border = sender as Border;
string tag = border.Tag as string;
switch (tag)
{
case "Title":
//点击拨号键盘顶部时显示和隐藏键盘
if (this.gridSearchPanel.Margin == hide)
{
isshow = true;
timestart = DateTime.Now;
CompositionTarget.Rendering += OnCompositionTargetRendering;
}
else
{
isshow = false;
timestart = DateTime.Now;
CompositionTarget.Rendering += OnCompositionTargetRendering;
}
return;
case "*":
//删除所有数字
this.tbSearch.Text = string.Empty;
break;
case "#":
//删除最后一位
if (this.tbSearch.Text.Length > 0)
{
this.tbSearch.Text = this.tbSearch.Text.Substring(0, this.tbSearch.Text.Length - 1);
}
break;
default:
//追加
this.tbSearch.Text += tag;
break;
}
}
这里的 CompositionTarget.Rendering += OnCompositionTargetRendering; 后面再说
private void OnGestureListenerDragStarted(object sender, DragStartedGestureEventArgs e)
{
//记录手势产生时的初始信息
pointOrigin = e.GetPosition(this.LayoutRoot);
marginorigin = this.gridSearchPanel.Margin;
}
private void OnGestureListenerDragDelta(object sender, DragDeltaGestureEventArgs e)
{
//手势执行过程的操作
Point point = e.GetPosition(this.LayoutRoot);
int length = (int)(point.Y - pointOrigin.Y);
Thickness newmargin = new Thickness(0, marginorigin.Top + length, 0, 0);
if (newmargin.Top < show.Top)
{
this.gridSearchPanel.Margin = show;
}
else if (newmargin.Top > hide.Top)
{
this.gridSearchPanel.Margin = hide;
}
else
{
this.gridSearchPanel.Margin = newmargin;
}
}
private void OnGestureListenerDragCompleted(object sender, DragCompletedGestureEventArgs e)
{
//手势完成时的操作
if (e.VerticalVelocity > 1000)
{
//当向下滑动速度大于1000时,下拉键盘
isshow = false;
}
else if (e.VerticalVelocity < 0)
{
isshow = true;
}
else
{
//折中操作,靠近哪里就往哪里靠
Thickness margin = this.gridSearchPanel.Margin;
if (margin.Top - show.Top > hide.Top - margin.Top)
isshow = false;
else
isshow = true;
}
timestart = DateTime.Now;
CompositionTarget.Rendering += OnCompositionTargetRendering;
}
private void OnGestureListenerFlick(object sender, FlickGestureEventArgs e)
{
//当滑动屏幕手势产生时触发,这里可以不用
}
3、当执行 CompositionTarget.Rendering += OnCompositionTargetRendering; 后,在更新silverlight每一帧画面的时候,就会调用OnCompositionTargetRendering进行绘制,通过这个事件,我们可以让键盘上拉和下拉的时候有一个动画过度,而不会太生硬,下面定义这个事件函数来绘制过度效果
void OnCompositionTargetRendering(object sender, EventArgs args)
{
//速度(像素/毫秒)
double v = 3;
if (isshow)
{
//从当前位置移动到show
double time = (DateTime.Now - timestart).TotalMilliseconds;
if (time == 0)
{
time = 1;
}
double top = this.gridSearchPanel.Margin.Top - time * v;
if (top > show.Top)
{
Thickness margin = new Thickness(0, top, 0, 0);
this.gridSearchPanel.Margin = margin;
timestart = DateTime.Now;
}
else
{
this.gridSearchPanel.Margin = show;
CompositionTarget.Rendering -= OnCompositionTargetRendering;
}
}
else
{
//从当前位置移动到hide
double time = (DateTime.Now - timestart).TotalMilliseconds;
if (time == 0)
{
time = 1;
}
double top = this.gridSearchPanel.Margin.Top + time * v;
if (top < hide.Top)
{
Thickness margin = new Thickness(0, top, 0, 0);
this.gridSearchPanel.Margin = margin;
timestart = DateTime.Now;
}
else
{
this.gridSearchPanel.Margin = hide;
CompositionTarget.Rendering -= OnCompositionTargetRendering;
}
}
}
大功告成了 : )