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。我认为使用它会导致它工作,但没有。有帮助吗?提前谢谢。
答案 0 :(得分:0)
好的,我明白了。我将每个文本框绑定到属性。当修改这些文本框中的任何一个时,ViewModel的绑定属性将相互更新。当发生这种情况时,它们会更新文本框,而不仅仅是属性,因为它是双向绑定。因此,当存在由用户输入引起的更新时,它会更新。当用户没有在该文本框中键入任何内容时(当从算法中更新文本框时,它不应该。
我的解决方案是在ImmediateTextBox中创建一个布尔属性“isUser”。当我调用我的重写的OnKeyDown或OnMouseLeftButtonPressed时,我将isUser设置为true。当用户输入或粘贴内容时文本发生变化时,我更新绑定并将isUser设置为false。