对我来说是个合理的要求。AppendText绝对是非常快的,因为它处理指针。在MVVM世界中,几乎每个答案都是子类,或者附加属性。
您可以创建新的接口,称之为ITextBuffer。
代码语言:javascript运行复制public interface ITextBuffer
{
void Delete();
void Delete(int offset, int length);
void Append(string content);
void Append(string content, int offset);
string GetCurrentValue();
event EventHandler
}
internal class MyTextBuffer : ITextBuffer
{
#region Implementation of ITextBuffer
private readonly StringBuilder _buffer = new StringBuilder();
public void Delete()
{
_buffer.Clear();
}
public void Delete(int offset, int length)
{
_buffer.Remove(offset, length);
}
public void Append(string content)
{
_buffer.Append(content);
var @event = BufferAppendedHandler;
if (@event != null)
@event(this, content);
}
public void Append(string content, int offset)
{
if (offset == _buffer.Length)
{
_buffer.Append(content);
}
else
{
_buffer.Insert(offset, content);
}
}
public string GetCurrentValue()
{
return _buffer.ToString();
}
public event EventHandler
#endregion
}这将在整个视图模型中使用。您现在要做的就是编写一个附加的属性,在进行绑定时,该属性会提前到这样的接口。
就像这样:
代码语言:javascript运行复制public sealed class MvvmTextBox
{
public static readonly DependencyProperty BufferProperty =
DependencyProperty.RegisterAttached(
"Buffer",
typeof (ITextBuffer),
typeof (MvvmTextBox),
new UIPropertyMetadata(null, PropertyChangedCallback)
);
private static void PropertyChangedCallback(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs depPropChangedEvArgs)
{
// todo: unrelease old buffer.
var textBox = (TextBox) dependencyObject;
var textBuffer = (ITextBuffer) depPropChangedEvArgs.NewValue;
var detectChanges = true;
textBox.Text = textBuffer.GetCurrentValue();
textBuffer.BufferAppendedHandler += (sender, appendedText) =>
{
detectChanges = false;
textBox.AppendText(appendedText);
detectChanges = true;
};
// todo unrelease event handlers.
textBox.TextChanged += (sender, args) =>
{
if (!detectChanges)
return;
foreach (var change in args.Changes)
{
if (change.AddedLength > 0)
{
var addedContent = textBox.Text.Substring(
change.Offset, change.AddedLength);
textBuffer.Append(addedContent, change.Offset);
}
else
{
textBuffer.Delete(change.Offset, change.RemovedLength);
}
}
Debug.WriteLine(textBuffer.GetCurrentValue());
};
}
public static void SetBuffer(UIElement element, Boolean value)
{
element.SetValue(BufferProperty, value);
}
public static ITextBuffer GetBuffer(UIElement element)
{
return (ITextBuffer)element.GetValue(BufferProperty);
}
}这里的想法是将StringBuilder包装到接口中(默认情况下它不会引发事件:),然后附加属性& TextBox实际实现可以利用该接口。
在您的视图模型中,您可能需要这样的东西:
代码语言:javascript运行复制public class MyViewModel
{
public ITextBuffer Description { get; set; }
public MyViewModel()
{
Description= new MyTextBuffer();
Description.Append("Just testing out.");
}
}并认为:
代码语言:javascript运行复制