Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:使用dispatcher在文本框中移动插入符号与不使用它_C#_.net_Wpf_Xaml - Fatal编程技术网

C# WPF:使用dispatcher在文本框中移动插入符号与不使用它

C# WPF:使用dispatcher在文本框中移动插入符号与不使用它,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我有一个文本框,我想在其中根据GotFocus和LostFocus事件移动插入符号。在GotFocus上,我必须使用调度程序来移动它,没有它,移动就不会发生。在LostFocus上,我也尝试过使用dispatcher,但当我使用它时,插入符号没有移动。我在没有调度程序的情况下移动了插入符号索引,移动发生了 我想知道这两种方法有什么区别,在什么情况下我应该使用它们 文本框的XAML: <TextBox Margin="75,25,30,0" LostFocus="MoveCarretToSt

我有一个文本框,我想在其中根据GotFocus和LostFocus事件移动插入符号。在GotFocus上,我必须使用调度程序来移动它,没有它,移动就不会发生。在LostFocus上,我也尝试过使用dispatcher,但当我使用它时,插入符号没有移动。我在没有调度程序的情况下移动了插入符号索引,移动发生了

我想知道这两种方法有什么区别,在什么情况下我应该使用它们

文本框的XAML:

<TextBox Margin="75,25,30,0" LostFocus="MoveCarretToStart" GotFocus="MoveCarretToEnd" Background="Transparent"   MaxLength="100" Height="25" BorderThickness="0,0,0,1" Name="LabelFreeText" Width="Auto" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="12" FontStyle="Italic"> 
无论是否调用,GotFocus和LostFocus事件都可以正常工作。但是,如果在鼠标事件而不是键盘事件后触发GotFocus,插入符号将自动移动到鼠标位置。由于MouseDown事件是在GotFocus之后处理的,插入符号索引将被下一个事件覆盖

您可以使用PreviewMouseDown禁用此自动行为:

BeginInvoke之所以能成功,是因为。您所做的基本上是将插入符号的移动推迟到事件队列的末尾,以便最后要处理的是CaretIndex的更改:

private void MoveCarretToEnd(object sender, RoutedEventArgs e)
{
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
        //wait until current event queue is handled
    {
        LabelFreeText.CaretIndex = LabelFreeText.Text.Length;
    }));
}
无论是否调用,GotFocus和LostFocus事件都可以正常工作。但是,如果在鼠标事件而不是键盘事件后触发GotFocus,插入符号将自动移动到鼠标位置。事件和插入符号将在下一个事件索引后被覆盖

您可以使用PreviewMouseDown禁用此自动行为:

BeginInvoke之所以能成功,是因为。您所做的基本上是将插入符号的移动推迟到事件队列的末尾,以便最后要处理的是CaretIndex的更改:

private void MoveCarretToEnd(object sender, RoutedEventArgs e)
{
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
        //wait until current event queue is handled
    {
        LabelFreeText.CaretIndex = LabelFreeText.Text.Length;
    }));
}
了解:

WPF应用程序从两个线程开始:一个用于处理渲染,另一个用于管理UI

WPF使用路由事件,虽然事件可能会发出有关某个内容的信号,但它不一定已经呈现,而是排队。我不确定事件处理程序是否也在队列中,但这对于结论来说并不重要:有时您需要将事件处理程序中的操作与呈现队列同步,或者甚至通过指定正确的优先级来推迟它

/不是直接事件。请参阅,对于GotFocus,似乎您需要此同步,控件也可以设置插入符号,覆盖您在事件处理程序中设置的值,或者由于某些无效状态而忽略您的调用

对于那些来自winforms的用户,有一条经验法则:如果wpf事件处理程序中有明显的问题不起作用,请使用invoke进行尝试。

阅读:

WPF应用程序从两个线程开始:一个用于处理渲染,另一个用于管理UI

WPF使用路由事件,虽然事件可能会发出有关某个内容的信号,但它不一定已经呈现,而是排队。我不确定事件处理程序是否也在队列中,但这对于结论来说并不重要:有时您需要将事件处理程序中的操作与呈现队列同步,或者甚至通过指定正确的优先级来推迟它

/不是直接事件。请参阅,对于GotFocus,似乎您需要此同步,控件也可以设置插入符号,覆盖您在事件处理程序中设置的值,或者由于某些无效状态而忽略您的调用

对于那些来自winforms的用户,有一条经验法则:如果wpf事件处理程序中有明显的问题不起作用,请使用invoke进行尝试

private void MoveCarretToEnd(object sender, RoutedEventArgs e)
{
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
        //wait until current event queue is handled
    {
        LabelFreeText.CaretIndex = LabelFreeText.Text.Length;
    }));
}