답변:
스크롤 뷰어로 감싸십시오.
<ScrollViewer>
<TextBlock />
</ScrollViewer>
참고이 답변 TextBlock
은 원래 질문에서 요구 한대로 (읽기 전용 텍스트 요소)에 적용됩니다 .
TextBox
(편집 가능한 텍스트 요소) 에 스크롤 막대를 표시 하려면 ScrollViewer
연결된 속성 을 사용하십시오 .
<TextBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
이 두 가지 속성에 대한 유효한 값은 Disabled
, Auto
, Hidden
와 Visible
.
TextBlock
아닙니다 TextBox
.
지금 다음을 사용할 수 있습니다 :
<TextBox Name="myTextBox"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True">SOME TEXT
</TextBox>
TextBlock
하지 않은 것으로 해석 TextBox
했지만 두 번째 단락은 언급했습니다 TextBox
. 분명히,이 답변은 확실히 텍스트 상자에 가장 적합한 방법 이며, 내 텍스트 블록 에 대해 가장 잘 알고 있습니다. :)
더 나은 것 :
<Grid Width="Your-specified-value" >
<ScrollViewer>
<TextBlock Width="Auto" TextWrapping="Wrap" />
</ScrollViewer>
</Grid>
이렇게하면 그리드를 사용하지 않는 경우와 같이 텍스트 블록의 텍스트가 오버플로되지 않고 텍스트 블록 아래의 요소와 겹치지 않습니다. 텍스트 블록이 이미 다른 요소와 그리드에 있었지만 다른 솔루션을 시도했을 때 나에게 일어났습니다. 텍스트 블록의 너비는 자동이어야하며 그리드 요소에서 원하는 것을 지정해야합니다. 내 코드 에서이 작업을 수행했으며 아름답게 작동합니다. HTH.
<ScrollViewer Height="239" VerticalScrollBarVisibility="Auto">
<TextBox AcceptsReturn="True" TextWrapping="Wrap" LineHeight="10" />
</ScrollViewer>
XAML에서 스크롤하는 TextBox를 사용하여 텍스트 영역으로 사용하는 방법입니다.
TextBlock
없습니다 TextBox
.
이 답변은 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 MaxHeight="50"
Width="Auto"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<TextBlock Text="{Binding Path=}"
Style="{StaticResource TextStyle_Data}"
TextWrapping="Wrap" />
</ScrollViewer>
MaxHeight를 ScrollViewer에 넣어 다른 방법 으로이 작업을 수행하고 있습니다.
텍스트 줄을 더 많거나 적게 표시하려면 MaxHeight를 조정하십시오. 쉬운.
당신이 사용할 수있는
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
이들은 wpf의 속성입니다. 자세한 내용은
http://wpfbugs.blogspot.in/2014/02/wpf-layout-controls-scrollviewer.html
다른 사람 이이 문제를 겪고 있는지 모르지만 어떻게 든 내 UI를 어쨌든 내 UI를 엉망 TextBlock
으로 ScrollViewer
만들었습니다. 간단한 해결 방법으로TextBlock
a로 TextBox
이와 같은
<TextBox Name="textBlock" SelectionBrush="Transparent" Cursor="Arrow" IsReadOnly="True" Text="My Text" VerticalScrollBarVisibility="Auto">
스크롤 막대가있는 TextBox
것처럼 보이고 동작하는를 만듭니다 TextBlock
(디자이너에서 모두 수행 할 수 있음).
TextBlock
두 번 언급 한 것을 알 수 있습니다TextBox
.