我试图切换两个WPF文本框的文本,将插入符号设置为每个TextBox的末尾,并将这些插入符号位置滚动到视图中(这样每个TextBox的最后一个字符仍然可见)。
这是Window的简单版本:
<Window ...>
<StackPanel>
<TextBox x:Name="textBox1" Text="aaabbbcccd" Height="25" Width="100" Margin="2" />
<TextBox x:Name="textBox2" Text="aaaaabbbbbcccccd" Height="25" Width="100" Margin="2" />
<Button Content="Switch text" Width="70" Margin="4" Click="OnClick_button_switchText" />
</StackPanel>
</Window>
这是点击事件的代码隐藏:
private void OnClick_button_switchText( object sender, RoutedEventArgs e )
{
// Switch text
string text1 = textBox1.Text;
textBox1.Text = textBox2.Text;
textBox2.Text = text1;
// Scroll to last characters
textBox1.ScrollToEnd();
textBox2.ScrollToEnd();
}
不幸的是,ScrollToEnd()没有按预期工作:没有任何反应。因此,我也尝试了其他几种可能性 - 这些也没有做任何事情,直到我开始设定焦点:
private void OnClick_button_switchText( object sender, RoutedEventArgs e )
{
...
// 2nd try
textBox1.Focus();
textBox1.CaretIndex = textBox1.Text.Length;
textBox2.Focus();
textBox2.CaretIndex = textBox2.Text.Length;
// 3rd try
textBox1.Focus();
EditingCommands.MoveToLineEnd.Execute( null, textBox1 );
textBox2.Focus();
EditingCommands.MoveToLineEnd.Execute( null, textBox2 );
// 4th try
textBox1.Focus();
Rect a_charIndexRect = textBox1.GetRectFromCharacterIndex( textBox1.CaretIndex );
textBox1.ScrollToHorizontalOffset( a_charIndexRect.Right );
textBox2.Focus();
a_charIndexRect = textBox2.GetRectFromCharacterIndex( textBox2.CaretIndex );
textBox2.ScrollToHorizontalOffset( a_charIndexRect.Right );
}
如果焦点设置在实际滚动方法之前它几乎可以工作(第二和第三种可能):textBox2正确显示文本,但textBox1仍然不滚动到结尾 - 但它确实将插入符号设置为结束。
如果按Tab键聚焦此控件,您会注意到光标位于末尾,但不在视野范围内。
所以我认为这可能是某种时间问题,并尝试在&#34; GotFocus&#34;内执行相应的滚动方法。 TextBoxes的事件,但没有任何成功。
有没有办法切换两个TextBox的文本并仍然显示最后的字符?
任何帮助将不胜感激。
答案 0 :(得分:0)
经过几次尝试和Peter Duniho发布的提示后,我发现了如何做到这一点
请注意,这仍然不是一个完美的解决方案,因为它不是MVVM方法 - 而是一种工作方式。
如果要在滚动到结尾后聚焦其中一个TextBox,则必须使用不同的方法:
private void OnClick_button_switchText( object sender, RoutedEventArgs e )
{
// Switch text
string text1 = textBox1.Text;
textBox1.Text = textBox2.Text;
textBox2.Text = text1;
// Scroll to end - without focus
textBox1.ScrollToHorizontalOffset( double.PositiveInfinity );
textBox2.ScrollToHorizontalOffset( double.PositiveInfinity );
// Scroll to end - and focus the first TextBox
textBox1.Focus();
EditingCommands.MoveToLineEnd.Execute( null, textBox1 );
textBox2.ScrollToHorizontalOffset( double.PositiveInfinity );
// Scroll to end - and focus the second TextBox
textBox1.ScrollToHorizontalOffset( double.PositiveInfinity );
textBox2.Focus();
EditingCommands.MoveToLineEnd.Execute( null, textBox2 );
}
编辑:这是我的MVVM方法(我保留现有的焦点)
<Window ...>
<StackPanel>
<TextBox x:Name="textBox1" Text="{Binding Text1}" behaviors:TextBoxScrollToEndBehavior.ScrollToEndOnEnabledBehavior="True" Height="25" Width="100" Margin="2"/>
<TextBox x:Name="textBox2" Text="{Binding Text2}" behaviors:TextBoxScrollToEndBehavior.ScrollToEndOnEnabledBehavior="True" Height="25" Width="100" Margin="2"/>
<Button Content="Switch text" Width="70" Margin="4" Command="{Binding CommandSwitchText}" />
</StackPanel>
</Window>
视图模型:
using Behaviors;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
namespace ViewModels
{
class MainWindowViewModel : ObservableObject
{
public MainWindowViewModel()
{
CommandSwitchText = new RelayCommand( SwitchText );
}
public RelayCommand CommandSwitchText
{
get;
private set;
}
private void SwitchText()
{
TextBoxScrollToEndBehavior.IsActive = true;
string textTemp = Text1;
Text1 = Text2;
Text2 = textTemp;
TextBoxScrollToEndBehavior.IsActive = false;
}
private string _text1 = "aaabbbcccd";
public string Text1
{
get
{
return _text1;
}
set
{
_text1 = value;
RaisePropertyChanged();
}
}
private string _text2 = "aaaaabbbbbcccccd";
public string Text2
{
get
{
return _text2;
}
set
{
_text2 = value;
RaisePropertyChanged();
}
}
}
}
行为:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace Behaviors
{
public static class TextBoxScrollToEndBehavior
{
private static bool _isActive = false;
public static bool IsActive
{
get
{
return _isActive;
}
set
{
_isActive = value;
}
}
public static readonly DependencyProperty ScrollToEndOnEnabledBehavior =
DependencyProperty.RegisterAttached( "ScrollToEndOnEnabledBehavior",
typeof( bool ),
typeof( TextBoxScrollToEndBehavior ),
new UIPropertyMetadata( false, OnScrollToEndOnEnabledBehavior ) );
public static bool GetScrollToEndOnEnabledBehavior( DependencyObject obj )
{
return (bool)obj.GetValue( ScrollToEndOnEnabledBehavior );
}
public static void SetScrollToEndOnEnabledBehavior( DependencyObject obj, bool value )
{
obj.SetValue( ScrollToEndOnEnabledBehavior, value );
}
private static void OnScrollToEndOnEnabledBehavior( object sender, DependencyPropertyChangedEventArgs e )
{
TextBox textBox = sender as TextBox;
if( textBox != null )
{
bool isEnabled = (bool)e.NewValue;
if( isEnabled )
{
textBox.TextChanged += OnTextChanged_textBox;
}
else
{
textBox.TextChanged -= OnTextChanged_textBox;
}
}
}
static void OnTextChanged_textBox( object sender, TextChangedEventArgs e )
{
TextBox textBox = sender as TextBox;
if( null != textBox )
{
if( IsActive )
{
if( textBox.IsFocused )
{
EditingCommands.MoveToLineEnd.Execute( null, textBox );
}
else
{
textBox.ScrollToHorizontalOffset( double.PositiveInfinity );
}
}
}
}
}
}