Silverlight 4重载文本框的textchanged事件由父文本框触发

时间:2011-09-27 17:37:43

标签: silverlight-4.0 textbox textchanged

我有一个来自http://blog.roboblob.com/2010/07/16/custom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding/comment-page-1/的自定义文本框:

public class ImmediateTextBox : TextBox
{
    public ImmediateTextBox()
    {
        this.Loaded += ImmediateTextBox_Loaded;
    }

    void ImmediateTextBox_Loaded(object sender, RoutedEventArgs e)
    {            
        this.GotFocus +=  ImmediateTextBox_GotFocus;
        this.TextChanged += new TextChangedEventHandler(ImmediateTextBox_TextChanged);
    }

    void ImmediateTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox txt = sender as TextBox;

        if (txt != null)
        {
            BindingExpression bindExp = txt.GetBindingExpression(TextBox.TextProperty);
            if (bindExp != null)
            {
                bindExp.UpdateSource();
            }//if

        }//if

    }

    void ImmediateTextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        this.SelectAll();
    }
 }

在我的xaml中我使用它,它工作正常,除非我嵌套它并且父容器有一个ImmediateTextBox:

 <ItemsControl Grid.Column="1" ItemsSource="{Binding Path=LstForecast}">
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
                    <customControls:ImmediateTextBox Padding="8" Height="36" Text="{Binding Path=DForecastQuantityShippedTotal,
                                                                                StringFormat=\{0:n0\},
                                                                                Mode=TwoWay,
                                                                                Converter={StaticResource StringToNullableDoubleConverter}}"
                                                                                 Width="70" IsEnabled="{Binding Path=IsForecastUserEditable}"/>
            <!--Weeks-->
            <ItemsControl ItemsSource="{Binding Path=LstWeeks}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                                    <customControls:ImmediateTextBox Padding="8" Width="70" Height="36"
                                                                                    Text="{Binding Path=DForecastQuantityShippedTotal, StringFormat=\{0:n0\}, Mode=TwoWay, Converter={StaticResource StringToNullableDoubleConverter}}"
                                                                                    IsEnabled="{Binding Path=IsForecastUserEditable}"/>
                            <!--days data-->
                            <ItemsControl ItemsSource="{Binding Path=LstDays}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal" />
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                                <customControls:ImmediateTextBox Padding="8" Width="70" Height="36"
                                                                                                             Text="{Binding Path=DForecastAutoManual,
                                                                                                                            StringFormat=\{0:n0\},
                                                                                                                            Mode=TwoWay,
                                                                                                              Converter={StaticResource StringToNullableDoubleConverter}}"
                                                                                                             IsEnabled="{Binding Path=IsForecastUserEditable}"/>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                            <!--end days data-->
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
            <!--end weeks-->
        </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>

在最低级别它真的很时髦。修改前一个,有时是后面生成的文本框。如果我使用自动完成框,当然它可以工作。问题是我想在文本框中添加行为以进行复制/粘贴/选择等,而我无法使用自动完成框,因为没有selectedtext或selectall()方法。我还注意到在RoutedEventArgs中,originalsource为null。我认为使用它会导致它工作,但没有。有帮助吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

好的,我明白了。我将每个文本框绑定到属性。当修改这些文本框中的任何一个时,ViewModel的绑定属性将相互更新。当发生这种情况时,它们会更新文本框,而不仅仅是属性,因为它是双向绑定。因此,当存在由用户输入引起的更新时,它会更新。当用户没有在该文本框中键入任何内容时(当从算法中更新文本框时,它不应该。

我的解决方案是在ImmediateTextBox中创建一个布尔属性“isUser”。当我调用我的重写的OnKeyDown或OnMouseLeftButtonPressed时,我将isUser设置为true。当用户输入或粘贴内容时文本发生变化时,我更新绑定并将isUser设置为false。