WPFにTextBlock
があります。私はその垂直方向の高さをはるかに超えて、それにたくさんの行を書きます。私はそれが起こるとき垂直スクロールバーが自動的に現れることを期待しました、しかしそれはしませんでした。プロパティペインでスクロールバーのプロパティを検索しようとしましたが、見つかりませんでした。
内容が高さを超えたら、TextBlock
用に垂直スクロールバーを自動的に作成する方法を教えてください。
明確化:私はむしろXAMLに直接書くことによってではなく、デザイナーからそれをしたいと思います。
スクロールビューアでラップします。
<ScrollViewer>
<TextBlock />
</ScrollViewer>
NOTEこの答えは、元の質問で求められているようにTextBlock
(読み取り専用のテキスト要素)に適用されます。
スクロールバーをTextBox
(編集可能なテキスト要素)に表示したい場合は、ScrollViewer
添付プロパティを使用します。
<TextBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
これら2つのプロパティの有効な値はDisabled
、Auto
、Hidden
およびVisible
です。
今すぐ以下を使用することができます。
<TextBox Name="myTextBox"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True">SOME TEXT
</TextBox>
もっと良いものがあります:
<Grid Width="Your-specified-value" >
<ScrollViewer>
<TextBlock Width="Auto" TextWrapping="Wrap" />
</ScrollViewer>
</Grid>
これにより、グリッドを使用しない場合のように、テキストブロック内のテキストがオーバーフローしてテキストブロックの下の要素に重なることがなくなります。テキストブロックがすでに他の要素とグリッドになっていても、他の解決策を試したときに私は起こりました。テキストブロックの幅はAutoでなければならず、Grid要素でを使用して希望する値を指定する必要があることに注意してください。私は自分のコードでこれをしました、そしてそれは美しく働きます。 HTH.
<ScrollViewer Height="239" VerticalScrollBarVisibility="Auto">
<TextBox AcceptsReturn="True" TextWrapping="Wrap" LineHeight="10" />
</ScrollViewer>
これは、XAMLでスクロールするTextBoxを使用し、それをテキスト領域として使用する方法です。
<ScrollViewer MaxHeight="50"
Width="Auto"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<TextBlock Text="{Binding Path=}"
Style="{StaticResource TextStyle_Data}"
TextWrapping="Wrap" />
</ScrollViewer>
私はScrollViewerにMaxHeightを置くことによって別の方法でこれをやっています。
MaxHeightを調整して、テキストの行数を増減してください。簡単です。
この回答では、MVVMを使用したソリューションについて説明します。
あなたが新しいロギングメッセージが追加されるたびに自動的に一番下までスクロールするロギングボックスをウィンドウに追加したいなら、この解決策は素晴らしいです。
これらの添付プロパティが追加されると、どこでも再利用できるため、非常にモジュール化された再利用可能なソフトウェアになります。
このXAMLを追加します。
<TextBox IsReadOnly="True"
Foreground="Gainsboro"
FontSize="13"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
attachedBehaviors:TextBoxApppendBehaviors.AppendText="{Binding LogBoxViewModel.AttachedPropertyAppend}"
attachedBehaviors:TextBoxClearBehavior.TextBoxClear="{Binding LogBoxViewModel.AttachedPropertyClear}"
TextWrapping="Wrap">
この添付プロパティを追加します。
public static class TextBoxApppendBehaviors
{
#region AppendText Attached Property
public static readonly DependencyProperty AppendTextProperty =
DependencyProperty.RegisterAttached(
"AppendText",
typeof (string),
typeof (TextBoxApppendBehaviors),
new UIPropertyMetadata(null, OnAppendTextChanged));
public static string GetAppendText(TextBox textBox)
{
return (string)textBox.GetValue(AppendTextProperty);
}
public static void SetAppendText(
TextBox textBox,
string value)
{
textBox.SetValue(AppendTextProperty, value);
}
private static void OnAppendTextChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs args)
{
if (args.NewValue == null)
{
return;
}
string toAppend = args.NewValue.ToString();
if (toAppend == "")
{
return;
}
TextBox textBox = d as TextBox;
textBox?.AppendText(toAppend);
textBox?.ScrollToEnd();
}
#endregion
}
そして、この添付プロパティ(ボックスをクリアする):
public static class TextBoxClearBehavior
{
public static readonly DependencyProperty TextBoxClearProperty =
DependencyProperty.RegisterAttached(
"TextBoxClear",
typeof(bool),
typeof(TextBoxClearBehavior),
new UIPropertyMetadata(false, OnTextBoxClearPropertyChanged));
public static bool GetTextBoxClear(DependencyObject obj)
{
return (bool)obj.GetValue(TextBoxClearProperty);
}
public static void SetTextBoxClear(DependencyObject obj, bool value)
{
obj.SetValue(TextBoxClearProperty, value);
}
private static void OnTextBoxClearPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs args)
{
if ((bool)args.NewValue == false)
{
return;
}
var textBox = (TextBox)d;
textBox?.Clear();
}
}
MEFなどの依存性注入フレームワークを使用している場合は、ロギング固有のコードをすべて独自のViewModelに配置できます。
public interface ILogBoxViewModel
{
void CmdAppend(string toAppend);
void CmdClear();
bool AttachedPropertyClear { get; set; }
string AttachedPropertyAppend { get; set; }
}
[Export(typeof(ILogBoxViewModel))]
public class LogBoxViewModel : ILogBoxViewModel, INotifyPropertyChanged
{
private readonly ILog _log = LogManager.GetLogger<LogBoxViewModel>();
private bool _attachedPropertyClear;
private string _attachedPropertyAppend;
public void CmdAppend(string toAppend)
{
string toLog = $"{DateTime.Now:HH:mm:ss} - {toAppend}\n";
// Attached properties only fire on a change. This means it will still work if we publish the same message twice.
AttachedPropertyAppend = "";
AttachedPropertyAppend = toLog;
_log.Info($"Appended to log box: {toAppend}.");
}
public void CmdClear()
{
AttachedPropertyClear = false;
AttachedPropertyClear = true;
_log.Info($"Cleared the GUI log box.");
}
public bool AttachedPropertyClear
{
get { return _attachedPropertyClear; }
set { _attachedPropertyClear = value; OnPropertyChanged(); }
}
public string AttachedPropertyAppend
{
get { return _attachedPropertyAppend; }
set { _attachedPropertyAppend = value; OnPropertyChanged(); }
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
これがどのように動作するのかです:
あなたが使用することができます
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
これらはwpfの添付プロパティです。詳細については
http://wpfbugs.blogspot.in/2014/02/wpf-layout-controls-scrollviewer.html
私はこれらの提案をテキストブロックに対して機能させることを試みましたが、それを機能させることができませんでした。私はそれをデザイナーから動かそうとさえしました。 (レイアウトを見て、一番下の下矢印 "V"をクリックしてリストを広げます)スクロールビューアをVisibleそしてAutoに設定しようとしましたが、それでもやはりできません動かない.
Readonly属性セットを使用して、最終的にTextBlock
をTextBox
に変更したところ、魅力的に機能しました。
他の誰かがこの問題を抱えているが、私のTextBlock
を何らかの形でScrollViewer
にラップして私のUIをめちゃくちゃにしていません - 簡単な回避策として、TextBlock
をTextBox
に置き換えることを考えました
<TextBox Name="textBlock" SelectionBrush="Transparent" Cursor="Arrow" IsReadOnly="True" Text="My Text" VerticalScrollBarVisibility="Auto">
スクロールバー付きのTextBox
のように見え、振る舞うTextBlock
を作成します(そしてデザイナーでそれをすべて行うことができます)。
これはその質問に対する簡単な解決策です。垂直スクロールは、テキストがオーバーフローしたときにのみアクティブになります。
<TextBox Text="Try typing some text here " ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="WrapWithOverflow" />