在做项目时经常会遇到一些问题,但在解决问题后没有来得及总结或记录,慢慢的就遗忘了。每当此时总是觉得有一丝丝遗憾,今天回想起一件过去的问题,随即提键记录。
开门见山,问题是这样的,向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将出错,这就需要你按需修改上面的模板了。