teratail header banner
teratail header banner
質問するログイン新規登録
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

7回答

2573閲覧

コンソールウインドウのようなテキストが流れるウインドウの作成

juntaro

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

0クリップ

投稿2019/03/08 08:21

1

0

質問させてください。
コンソール画面(ターミナル画面)のような、テキスト文字を出力する度にスクロールするウインドウを作成したいと思っています。
ある程度まではスクロールバーで過去の情報も表示しつつ、全てをTextBoxで保持するとメモリを消費し過ぎるので、どこかで最近の情報だけに
したいと思います。
バッファが溜まれば削除以外に何か良い方法はありますか?

開発環境:Visual Studio 2017 (WPF)
動作環境:Windows10

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

以下の記事が参考になると思います。

記事
WPF で PowerShell コンソールを作る

記事の中で紹介されているサンプルコード
WPF で Windows PowerShell コンソールを再現します。

投稿2019/03/08 11:01

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juntaro

2019/03/11 01:54

こういった本格的なPowerShellの出し方もあるんですね。 ご親切にサンプルもありがとうございます。 一度、検証してみます。
guest

0

ベストアンサー

たとえばこんな感じに ListBox と ObservableCollection<string> をバインドし、ObservableCollection の方にリミットをつけておけばいいのではないかと。

C#

1using System; 2using System.Collections.Generic; 3using System.Collections.ObjectModel; 4using System.ComponentModel; 5using System.Runtime.CompilerServices; 6using System.Windows.Input; 7 8namespace WpfApp1 9{ 10 public class ViewModel : INotifyPropertyChanged 11 { 12 public ViewModel() 13 { 14 EnterCommand = new ActionCommand(() => List.Add(CommandLine)); 15 } 16 17 public event PropertyChangedEventHandler PropertyChanged; 18 19 protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null) 20 { 21 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 22 } 23 24 protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null) 25 { 26 if (EqualityComparer<T>.Default.Equals(field, value)) return false; 27 field = value; 28 OnPropertyChanged(propertyName); 29 return true; 30 } 31 32 private string commandLine; 33 public string CommandLine 34 { 35 get => commandLine; 36 set => SetProperty(ref commandLine, value); 37 } 38 39 private ActionCommand enterCommand; 40 public ActionCommand EnterCommand 41 { 42 get => enterCommand; 43 set => SetProperty(ref enterCommand, value); 44 } 45 46 public OverflowableList List { get; } = new OverflowableList(); 47 } 48 49 public class ActionCommand : ICommand 50 { 51 public ActionCommand(Action action) 52 { 53 Action = action; 54 } 55 56 public Action Action { get; private set; } 57 58 public bool CanExecute(object parameter) 59 { 60 return true; 61 } 62 63 public void Execute(object parameter) 64 { 65 Action(); 66 } 67 68 public event EventHandler CanExecuteChanged; 69 } 70 71 public class OverflowableList : ObservableCollection<string> 72 { 73 protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null) 74 { 75 if (EqualityComparer<T>.Default.Equals(field, value)) return false; 76 field = value; 77 OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 78 return true; 79 } 80 81 protected virtual void Shrink() 82 { 83 while (Limit < Count) RemoveAt(0); 84 } 85 86 private int limit = 10; 87 public int Limit 88 { 89 get => limit; 90 set 91 { 92 if (SetProperty(ref limit, value)) 93 { 94 Shrink(); 95 } 96 } 97 } 98 99 protected override void InsertItem(int index, string item) 100 { 101 base.InsertItem(index, item); 102 Shrink(); 103 } 104 } 105} 106

XAML

1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Window.DataContext> 10 <local:ViewModel/> 11 </Window.DataContext> 12 <Grid> 13 <Grid.RowDefinitions> 14 <RowDefinition/> 15 <RowDefinition Height="Auto"/> 16 </Grid.RowDefinitions> 17 <ListBox Grid.Row="0" ItemsSource="{Binding List}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 18 <ListBox.ItemTemplate> 19 <DataTemplate> 20 <TextBlock TextWrapping="Wrap" Text="{Binding}"/> 21 </DataTemplate> 22 </ListBox.ItemTemplate> 23 </ListBox> 24 <Grid Grid.Row="1"> 25 <Grid.ColumnDefinitions> 26 <ColumnDefinition/> 27 <ColumnDefinition Width="Auto"/> 28 </Grid.ColumnDefinitions> 29 <TextBox Grid.Column="0" Text="{Binding CommandLine}"/> 30 <Button Grid.Column="1" Command="{Binding EnterCommand}">Click</Button> 31 </Grid> 32 </Grid> 33</Window> 34

投稿2019/03/08 11:58

編集2019/03/11 02:18
Zuishin

総合スコア28675

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juntaro

2019/03/11 01:57

長いサンプルまでありがとうございます。 大変、参考になりました。 長いけどシンプルな内容ですね。 順番をスワップするのではなく、RemoveAtを使用するという所が興味深いですね。 本当にありがとうございます。
juntaro

2019/03/11 01:57

長いサンプルまでありがとうございます。 大変、参考になりました。 長いけどシンプルな内容ですね。 順番をスワップするのではなく、RemoveAtを使用するという所が興味深いですね。 本当にありがとうございます。
guest

0

循環バッファ とか リングバッファ とか呼ばれるものが向いていると思います。

投稿2019/03/08 08:40

hihijiji

総合スコア4152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juntaro

2019/03/08 09:00

循環バッファですね。 早急のご回答ありがとうございます。初耳でした。 これからじっくり調べてみます。
guest

0

WindowsFormでやってる方法ですが(WPFでできるかどうかはわかりませんが)
TextBoxで追記していって、ある程度溜まった場合に(数M文字)、先頭からその容量の半分程度を削除して最終行にスクロールし直す、ということをやってます

・textbox.Selectで先頭から削除する容量まで選択
・textbox にDELキー送出
・最終行にカーソル移動
・textbox.ScrollCaretでスクロール

これでわりと違和感なく表示できてます

#他にいい方法があれば私も知りたいところです

投稿2019/03/08 08:38

y_waiwai

総合スコア88180

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juntaro

2019/03/08 09:01

具体的なご説明ありがとうございます。 何となく考えていた実現方法に近いです。 もっと良い方法があれば良いと私も考えています。
guest

0

http://www.woodensoldier.info/computer/csharptips/125.htm

textBox1.AppendText(message + "\r\n");

textBoxを使うなら、
AppendTextが最強なので、適当なタイミングで、消すをやればいいと思う。
TextのBindingでやると、遅い。全部のテキストを書き換えようとするからね。
差分書き換えみたいなことをできないといけない。
循環バッファ は、みたいな機構は、やりたいけど、専用のコントロールが必要そう。

投稿2019/03/08 10:53

kiichi54321

総合スコア1986

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juntaro

2019/03/11 01:51

さすがに全てを更新すると遅いですよね。 色々と試してみて早いものを採用しようと思います。 ありがとうございました。
guest

0

時間が経ちましたが、テストの結果、処理時間とシンプル性を考慮しまして、AppendTextで追加し、設定値より大きいサイズになった場合は半分程度に減らす処理としました。
ありがとうございました。

投稿2019/04/05 01:44

juntaro

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

様々なご回答、本当にありがとうございました。
一度、全ての手法を試してみて、最適な方法を取りたいと思います。
自分では思いつかないようなロジック、大変助かりました。
ありがとうございます。

投稿2019/03/15 06:31

juntaro

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問