SOが含まれていますが、提案されたソリューションは私の場合は機能しません。インターネット上で似たような質問がたくさんあります。
<TextBox Name="Status"
Margin="5"
Grid.Column="1"
Grid.Row="5"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="600"
Height="310"/>
いくつかの作業を行い、このテキストボックスに複数行(おそらく問題ですか?)メッセージを追加するコードビハインドのメソッドがあります。
private static void DoSomeThings(TextBox textBox)
{
// do work
textBox.AppendText("Work finished\r\n"); // better way than Text += according to msdn
// do more
textBox.AppendText("One more message\r\n");
...
}
private static void DoSomething2(TextBox textBox)
{
// same as first method
}
すべてのアクションが行われた後、テキストボックスの一番下までスクロールする必要があります。 ScrollToEnd()、ScrollToLine、テキストボックスをScrollViewerにラップ、選択およびキャレットの回避策を試み、ScrollToEndをTextChangedにアタッチしました。テキストボックスの高さを超える実行行を手動でスクロールする必要がある場合、これは機能しません。重複した質問で申し訳ありませんが、私は問題について新鮮なビジョンを持つ誰かがすぐに解決できるいくつかの小さな問題を見逃していると思います。前もって感謝します。
この質問によると、 TextBoxが非アクティブなタブにある場合、TextBox.ScrollToEndは機能しません
テキストボックスにフォーカスし、キャレットの位置を更新してから、スクロールして終了する必要があります。
Status.Focus();
Status.CaretIndex = Status.Text.Length;
Status.ScrollToEnd();
[〜#〜] edit [〜#〜]
テキストボックスの例:
<TextBox TextWrapping="Wrap" VerticalScrollBarVisibility="Auto"
AcceptsReturn="True" Name="textBox"/>
単純なカスタムコントロールにした場合、スクロールを行うためにコードビハインドは必要ありません。
public class ScrollingTextBox : TextBox {
protected override void OnInitialized (EventArgs e) {
base.OnInitialized(e);
VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
}
protected override void OnTextChanged (TextChangedEventArgs e) {
base.OnTextChanged(e);
CaretIndex = Text.Length;
ScrollToEnd();
}
}
WPFを使用している場合、コードビハインドでテキストボックスを渡すよりもバインディングを使用する方がはるかに優れています。
コードビハインドが気に入らない場合は、トリックを行うAttachedPropertyを次に示します。
namespace YourProject.YourAttachedProperties
{
public class TextBoxAttachedProperties
{
public static bool GetAutoScrollToEnd(DependencyObject obj)
{
return (bool)obj.GetValue(AutoScrollToEndProperty);
}
public static void SetAutoScrollToEnd(DependencyObject obj, bool value)
{
obj.SetValue(AutoScrollToEndProperty, value);
}
// Using a DependencyProperty as the backing store for AutoScrollToEnd. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AutoScrollToEndProperty =
DependencyProperty.RegisterAttached("AutoScrollToEnd", typeof(bool), typeof(TextBoxAttachedProperties), new PropertyMetadata(false, AutoScrollToEndPropertyChanged));
private static void AutoScrollToEndPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if(d is TextBox textbox && e.NewValue is bool mustAutoScroll)
{
textbox.TextChanged += (s, ee)=> AutoScrollToEnd(s, ee, textbox);
}
}
private static void AutoScrollToEnd(object sender, TextChangedEventArgs e, TextBox textbox)
{
textbox.ScrollToEnd();
}
}
}
そして、あなたのxamlでちょうどする:
<TextBox
AcceptsReturn="True"
myAttachedProperties:TextBoxAttachedProperties.AutoScrollToEnd="True"/>
Xamlファイルの先頭に追加することを忘れないでください
xmlns:myAttachedProperties="clr-namespace:YourProject.YourAttachedProperties"
そして出来上がり
ありがとう!元の焦点を覚えるためにこれを追加しました:
var oldFocusedElement = FocusManager.GetFocusedElement(this);
this.textBox.Focus();
this.textBox.CaretIndex = this.textBox.Text.Length;
this.textBox.ScrollToEnd();
FocusManager.SetFocusedElement(this, oldFocusedElement);