[Silverlight][WPF] 當滑鼠點選到TextBox時自動選取所有文字的方法

  • 16108
  • 0
  • C#
  • 2013-07-15

有時候為了考量到使用者操作時的便利性,會希望當使用者點選到文字輸入欄位時,會自動選取該欄位裡面所有的文字,以便編輯,這件事在Silverlight中非常容易就可以完成了,只要透過TextBox的SelectAll()方法就可以達成。
在WPF中就不太一樣囉!!

 

有時候為了考量到使用者操作時的便利性,會希望當使用者點選到文字輸入欄位時,會自動選取該欄位裡面所有的文字,以便編輯,這件事在Silverlight中非常容易就可以完成了,只要透過TextBoxSelectAll()方法就可以達成。

 

讓我們來看看Silverlight的範例先(請點選範例中的兩個文字輸入方塊):

上面範例的原始碼如下:

 

MainPage.xaml
<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>

 

MainPage.xaml.cs
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)的方式一文調整瀏覽器設定)

 

上方範例的原始碼如下:

Page1.xaml
<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>

 

Page1.xaml.cs
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都有一樣的效果:

App.xaml.cs
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();
        } 

    }
}

 

完成後的範例如下:

 

 

最後一樣附上專案原始檔,請自行服用: