windows phone 中 TextBox 的詭異事件 TextChanged


在做項目時經常會遇到一些問題,但在解決問題后沒有來得及總結或記錄,慢慢的就遺忘了。每當此時總是覺得有一絲絲遺憾,今天回想起一件過去的問題,隨即提鍵記錄。

開門見山,問題是這樣的,向TextBox中每輸入一個字符TextChanged事件會激發兩次,通過單步調試發現的確是執行了兩次。Why?

如圖:

代碼如下

前台XAML和后台 C#:

<phone:PhoneApplicationPage 
x:Class="TextBoxDemo1.MainPage"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone
="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell
="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable
="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily
="{StaticResource PhoneFontFamilyNormal}"
FontSize
="{StaticResource PhoneFontSizeNormal}"
Foreground
="{StaticResource PhoneForegroundBrush}"
SupportedOrientations
="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible
="True">

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="TextBoxDemo" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBox Name="textBox1" Height="72" Width="460" TextChanged="textBox1_TextChanged"/>
<TextBlock Name="textBlock1" />
</StackPanel>
</Grid>
</Grid>

</phone:PhoneApplicationPage>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace TextBoxDemo1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private int counter = 0;
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
textBlock1.Text += "文本改變次數:" + (++counter) + "\r\n";
}
}
}

為什么會這樣呢?通過網絡搜索找到了一張網頁http://stackoverflow.com/questions/3438806/textbox-textchanged-event-firing-twice-on-windows-phone-7-emulator

大致意思是TextBox的默認模板的問題,可以通過自定義模板來解決。按照該文的提示,我用Blend打開剛才的項目,並獲得默認模板。如圖:

取得默認模板后的XAML代碼如下:

 

  1 <phone:PhoneApplicationPage 
2 x:Class="TextBoxDemo1.MainPage"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
6 xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
7 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
8 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9 mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
10 FontFamily="{StaticResource PhoneFontFamilyNormal}"
11 FontSize="{StaticResource PhoneFontSizeNormal}"
12 Foreground="{StaticResource PhoneForegroundBrush}"
13 SupportedOrientations="Portrait" Orientation="Portrait"
14 shell:SystemTray.IsVisible="True">
15 <phone:PhoneApplicationPage.Resources>
16 <ControlTemplate x:Key="PhoneDisabledTextBoxTemplate" TargetType="TextBox">
17 <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
18 </ControlTemplate>
19 <Style x:Key="TextBoxStyle1" TargetType="TextBox">
20 <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
21 <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
22 <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
23 <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
24 <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
25 <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>
26 <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>
27 <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
28 <Setter Property="Padding" Value="2"/>
29 <Setter Property="Template">
30 <Setter.Value>
31 <ControlTemplate TargetType="TextBox">
32 <Grid Background="Transparent">
33 <VisualStateManager.VisualStateGroups>
34 <VisualStateGroup x:Name="CommonStates">
35 <VisualState x:Name="Normal"/>
36 <VisualState x:Name="MouseOver"/>
37 <VisualState x:Name="Disabled">
38 <Storyboard>
39 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
40 <DiscreteObjectKeyFrame KeyTime="0">
41 <DiscreteObjectKeyFrame.Value>
42 <Visibility>Collapsed</Visibility>
43 </DiscreteObjectKeyFrame.Value>
44 </DiscreteObjectKeyFrame>
45 </ObjectAnimationUsingKeyFrames>
46 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
47 <DiscreteObjectKeyFrame KeyTime="0">
48 <DiscreteObjectKeyFrame.Value>
49 <Visibility>Visible</Visibility>
50 </DiscreteObjectKeyFrame.Value>
51 </DiscreteObjectKeyFrame>
52 </ObjectAnimationUsingKeyFrames>
53 </Storyboard>
54 </VisualState>
55 <VisualState x:Name="ReadOnly">
56 <Storyboard>
57 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
58 <DiscreteObjectKeyFrame KeyTime="0">
59 <DiscreteObjectKeyFrame.Value>
60 <Visibility>Collapsed</Visibility>
61 </DiscreteObjectKeyFrame.Value>
62 </DiscreteObjectKeyFrame>
63 </ObjectAnimationUsingKeyFrames>
64 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
65 <DiscreteObjectKeyFrame KeyTime="0">
66 <DiscreteObjectKeyFrame.Value>
67 <Visibility>Visible</Visibility>
68 </DiscreteObjectKeyFrame.Value>
69 </DiscreteObjectKeyFrame>
70 </ObjectAnimationUsingKeyFrames>
71 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledOrReadonlyBorder">
72 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
73 </ObjectAnimationUsingKeyFrames>
74 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="DisabledOrReadonlyBorder">
75 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
76 </ObjectAnimationUsingKeyFrames>
77 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent">
78 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>
79 </ObjectAnimationUsingKeyFrames>
80 </Storyboard>
81 </VisualState>
82 </VisualStateGroup>
83 <VisualStateGroup x:Name="FocusStates">
84 <VisualState x:Name="Focused">
85 <Storyboard>
86 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="EnabledBorder">
87 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>
88 </ObjectAnimationUsingKeyFrames>
89 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder">
90 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>
91 </ObjectAnimationUsingKeyFrames>
92 </Storyboard>
93 </VisualState>
94 <VisualState x:Name="Unfocused"/>
95 </VisualStateGroup>
96 </VisualStateManager.VisualStateGroups>
97 <Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">
98 <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
99 </Border>
100 <Border x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed">
101 <TextBox x:Name="DisabledOrReadonlyContent" Background="Transparent" Foreground="{StaticResource PhoneDisabledBrush}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}" SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}" TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/>
102 </Border>
103 </Grid>
104 </ControlTemplate>
105 </Setter.Value>
106 </Setter>
107 </Style>
108 </phone:PhoneApplicationPage.Resources>
109
110 <!--LayoutRoot is the root grid where all page content is placed-->
111 <Grid x:Name="LayoutRoot" Background="Transparent">
112 <Grid.RowDefinitions>
113 <RowDefinition Height="Auto"/>
114 <RowDefinition Height="*"/>
115 </Grid.RowDefinitions>
116
117 <!--TitlePanel contains the name of the application and page title-->
118 <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
119 <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
120 <TextBlock x:Name="PageTitle" Text="TextBoxDemo" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
121 </StackPanel>
122
123 <!--ContentPanel - place additional content here-->
124 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
125 <StackPanel>
126 <TextBox Name="textBox1" Height="72" Width="460" TextChanged="textBox1_TextChanged" Style="{StaticResource TextBoxStyle1}"/>
127 <TextBlock Name="textBlock1" />
128 </StackPanel>
129 </Grid>
130 </Grid>
131
132 </phone:PhoneApplicationPage>

問題找到了,在第101行,發現里面又嵌套了一個TextBox。最簡單的辦法就是將第100到102行注釋掉,先試試:

果然可以,不過如果你需要將textBox1的IsEnabled設置成False或將IsReadOnly設置成True將出錯,這就需要你按需修改上面的模板了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM