有時候為了考量到使用者操作時的便利性,會希望當使用者點選到文字輸入欄位時,會自動選取該欄位裡面所有的文字,以便編輯,這件事在Silverlight中非常容易就可以完成了,只要透過TextBox的SelectAll()方法就可以達成。
在WPF中就不太一樣囉!!
有時候為了考量到使用者操作時的便利性,會希望當使用者點選到文字輸入欄位時,會自動選取該欄位裡面所有的文字,以便編輯,這件事在Silverlight中非常容易就可以完成了,只要透過TextBox的SelectAll()方法就可以達成。
讓我們來看看Silverlight的範例先(請點選範例中的兩個文字輸入方塊):
上面範例的原始碼如下:
<UserControl x:Class="SL_TextBoxSelectAll.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
Width="600" Height="150" d:DesignWidth="800" d:DesignHeight="600">
<Border BorderThickness="2" CornerRadius="10" BorderBrush="#FF323232" Background="White">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox x:Name="txtNormal" Grid.Row="2" Text="我是普通的TextBox" FontSize="16"
d:LayoutOverrides="Height" VerticalAlignment="Center" Margin="10,0" />
<TextBox x:Name="txtAutoSelectAll" Grid.Column="1" Grid.Row="2" Text="點到我會自動選取所有文字"
FontSize="16" d:LayoutOverrides="Height" VerticalAlignment="Center"
Margin="10,0" />
<TextBlock TextWrapping="Wrap" Text="預設的TextBox" d:LayoutOverrides="Width, Height"
FontSize="16" Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock TextWrapping="Wrap" Text="加上事件處理的TextBox" d:LayoutOverrides="Width, Height"
Grid.Column="1" FontSize="16" Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock TextWrapping="Wrap" Text="Silverlight版本" FontSize="21.333"
HorizontalAlignment="Center" d:LayoutOverrides="Height" Grid.ColumnSpan="2"
VerticalAlignment="Center" Foreground="#FFC8C8C8" FontWeight="Bold">
<TextBlock.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="3" />
</TextBlock.Effect>
</TextBlock>
</Grid>
</Border>
</UserControl>
using System.Windows;
using System.Windows.Controls;
namespace SL_TextBoxSelectAll
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
//只要幫TextBox的GotFocus觸發時執行SelectAll()方法即可
txtAutoSelectAll.GotFocus += SelectAllText;
}
private void SelectAllText( object sender , RoutedEventArgs e )
{
var textBox = e.OriginalSource as TextBox;
if( textBox != null )
{
textBox.SelectAll();
}
}
}
}
如果在WPF中依樣畫葫蘆呢?~很開心的....成果跟想像中會有很大的落差,得再加上PreviewMouseLeftButtonDown這個事件來多一點事才行,讓我們看看下面的WPF版範例。
(*若無法正常瀏覽本文WPF版範例,煩請參考[Windows7]使用IE9、FireFox與Chrome瀏覽WPF Browser Application(.XBAP)的方式一文調整瀏覽器設定)
上方範例的原始碼如下:
<Page x:Class="Wpf_TextBoxSelectAll.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" Width="600"
Height="150" d:DesignWidth="800" d:DesignHeight="600" Title="Page1"
ShowsNavigationUI="False">
<Border BorderThickness="2" CornerRadius="10" BorderBrush="#FF323232" Background="White">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox x:Name="txtNormal" Grid.Row="2" Text="我是加上GotFocus事件的TextBox" FontSize="16"
d:LayoutOverrides="Height" VerticalAlignment="Center" Margin="10,0" />
<TextBox x:Name="txtAutoSelectAll" Grid.Column="1" Grid.Row="2" Text="點到我會自動選取所有文字"
FontSize="16" d:LayoutOverrides="Height" VerticalAlignment="Center"
Margin="10,0" />
<TextBlock TextWrapping="Wrap" Text="加上GotFocus事件的TextBox"
d:LayoutOverrides="Width, Height" FontSize="16" Grid.Row="1"
VerticalAlignment="Center" HorizontalAlignment="Center" />
<TextBlock TextWrapping="Wrap" Text="加上事件處理的TextBox" d:LayoutOverrides="Width, Height"
Grid.Column="1" FontSize="16" Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock TextWrapping="Wrap" Text="WPF版本" FontSize="21.333"
HorizontalAlignment="Center" d:LayoutOverrides="Height" Grid.ColumnSpan="2"
VerticalAlignment="Center" Foreground="Black" FontWeight="Bold">
</TextBlock>
</Grid>
</Border>
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Wpf_TextBoxSelectAll
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
txtAutoSelectAll.GotFocus += SelectAllText;
txtNormal.GotFocus += SelectAllText;
//得在放開滑鼠左鍵的事件中多做點事才行~
txtAutoSelectAll.PreviewMouseLeftButtonDown += TextBox_PreviewMouseLeftButtonDown;
}
private void TextBox_PreviewMouseLeftButtonDown( object sender , MouseButtonEventArgs e )
{
var textbox = ( sender as TextBox );
//多判斷鍵盤的焦點是否在被選到的TextBox上
if( textbox != null && textbox.IsKeyboardFocusWithin == false )
{
//觸發事件的東西居然是TextBoxView,而不是TextBox本身喔!!所以得動手腳轉移焦點~
if( e.OriginalSource.GetType().Name == "TextBoxView" )
{
e.Handled = true;
textbox.Focus();
}
}
}
private void SelectAllText( object sender , RoutedEventArgs e )
{
var textBox = e.OriginalSource as TextBox;
if( textBox != null )
{
textBox.SelectAll();
}
}
}
}
但是如果頁面上有一大堆的TextBox都想這樣做,那不就得加EventHandler加到中風了嗎!?還好WPF中有一個好用的類別可以幫我們解決這個問題—EventManager
我們可以在App.xaml.cs中透過EventManager來對所有的TextBox來動手腳,讓整個專案中所有的TextBox都有一樣的效果:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Controls;
using System.Windows.Input;
namespace Wpf_TextBoxSelectAllEnhanced
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup( StartupEventArgs e )
{
EventManager.RegisterClassHandler( typeof( TextBox ) , UIElement.PreviewMouseLeftButtonDownEvent ,
new MouseButtonEventHandler( TextBox_PreviewMouseLeftButtonDown ) , true );
EventManager.RegisterClassHandler( typeof( TextBox ) , UIElement.GotKeyboardFocusEvent ,
new RoutedEventHandler( SelectAllText ) , true );
base.OnStartup( e );
}
private static void TextBox_PreviewMouseLeftButtonDown( object sender , MouseButtonEventArgs e )
{
var textbox = ( sender as TextBox );
if( textbox != null && textbox.IsKeyboardFocusWithin != true )
{
if( e.OriginalSource.GetType().Name == "TextBoxView" )
{
e.Handled = true;
textbox.Focus();
}
}
}
private static void SelectAllText( object sender , RoutedEventArgs e )
{
var textBox = e.OriginalSource as TextBox;
if( textBox != null )
textBox.SelectAll();
}
}
}
完成後的範例如下:
最後一樣附上專案原始檔,請自行服用: