2009-10-23 4 views
1

Je travaille sur un éditeur de texte basé sur RichEditBox. J'ai implémenté la fonctionnalité "Aller à la ligne" qui se résout finalement à TextPointer.Paragraph.BringIntoView();Paragraph.BringIntoView() ne fonctionne que lorsqu'il est mis au point

En plus de cela, je règle également la position du curseur. Ce que j'ai découvert est que BringIntoView ne fonctionne que lorsque je clique sur le RichEditBox d'abord (le mettre au point). Sinon, il semble être ignoré. Je peux voir que la position du curseur a été ajustée par le code autour de BringIntoView.

Est-ce que quelqu'un sait quelle est la raison/la nature de ce problème? Comment puis-je le surmonter?

+0

De quel langage/SDK parlez-vous? –

+0

Désolé, j'étais si profond dans le problème que j'ai oublié les détails ... Le projet est en C# et WPF. J'utilise .NET 3.5 Toutes les idées seraient appréciées. – pavele

+0

Je suis également confronté à cela, et je suppose qu'il est fortement lié à [un autre problème] (http://social.msdn.microsoft.com/Forums/vstudio/en-US/d9fdf56c-a651-4c9b-b0c6- 9a74eca3840d/comment définir la propriété readonly-property-selection-on-a-flowdocumentscrollviewer? Forum = wpf # 2960f16a-c66d-4ef7-b91a-eadb655a3762) où la sélection ne peut pas être définie avant que l'utilisateur ne clique dans la fenêtre. Il est assez frustrant que Microsoft ne corrige pas ces problèmes. On se sent comme WPF est utilisé par une petite minorité. –

Répondre

0

Ne pouvez-vous pas donner d'abord le focus RichTextBox (?) Puis, en utilisant Keyboard.Focus(richTextBox) ou richTextBox.Focus()?

+0

Bien sûr, j'ai essayé cela en premier. Cela n'aide pas. Mais même si c'est le cas, cela pourrait ne pas être tout à fait correct (changer le focus) dans le contexte de l'interface utilisateur de l'application. – pavele

1

trouvé de solution cela, pas sûr si cela va fonctionner dans un environnement pur WPF, dans mon cas, je suis en WPF dans une solution principalement Windows Forms à l'aide UserControls WPF en cas de besoin. Au lieu d'appeler immédiatement BringIntoFocus() immédiatement, reportez-le à une file d'attente qui est gérée par un temporisateur. Par exemple:

System.Windows.Forms.Timer DeferredActionTimer = new System.Windows.Forms.Timer() { Interval = 200 }; 

Queue<Action> DeferredActions = new Queue<Action>(); 

void DeferredActionTimer_Tick(object sender, EventArgs e) { 
    while(DeferredActions.Count > 0) { 
    Action act = DeferredActions.Dequeue(); 
    act(); 
    } 
} 

Dans votre constructeur de formes, ou en cas OnLoad ajouter:

DeferredActionTimer.Tick += new EventHandler(DeferredActionTimer_Tick); 
DeferredActionTimer.Enabled = true; 

Enfin, au lieu d'appeler directement TextPointer.Paragraph.BringIntoView();, appelez comme ceci:

DeferredActions.Enqueue(() => TextPointer.Paragraph.BringIntoView()); 

Remarque que la minuterie Windows Forms déclenche des événements dans le thread principal (via la boucle de pompe de message). Si vous devez utiliser une autre minuterie, vous avez besoin d'un peu de code supplémentaire. Je vous recommande d'utiliser System.Timers.Timer plutôt que le System.Threading.Timer (c'est un peu plus sûr pour les threads). Vous devez également inclure l'action dans une structure Dispatcher.Invoke. Dans mon cas, la minuterie WinForms fonctionne comme un charme.

Questions connexes