using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace Tango.SharedUI.Components
{
/// <summary>
/// Represents an MVVM TextBox controller
/// </summary>
/// <seealso cref="System.Windows.DependencyObject" />
public class TextController : DependencyObject
{
private TextBox _textBox;
private bool _isMouseDown;
/// <summary>
/// Determines whether an element is Controller.
/// </summary>
public static readonly DependencyProperty ControllerProperty =
DependencyProperty.RegisterAttached("Controller",
typeof(TextController), typeof(TextController),
new FrameworkPropertyMetadata(null,ControllerChanged));
/// <summary>
/// On controller changed.
/// </summary>
/// <param name="d">The d.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
/// <exception cref="System.ArgumentException">The text controller component can only handle elements of type TextBox.</exception>
private static void ControllerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d != null && e.NewValue != null)
{
if (!(d is TextBox))
{
throw new ArgumentException("The text controller component can only handle elements of type TextBox.");
}
(e.NewValue as TextController).SetTextBox(d as TextBox);
}
}
/// <summary>
/// Sets the Controller attached property.
/// </summary>
/// <param name="element">The element.</param>
/// <param name="value">if set to <c>true</c> [value].</param>
public static void SetController(FrameworkElement element, TextController value)
{
element.SetValue(ControllerProperty, value);
}
/// <summary>
/// Gets the Controller attached property.
/// </summary>
/// <param name="element">The element.</param>
/// <returns></returns>
public static TextController GetController(FrameworkElement element)
{
return (TextController)element.GetValue(ControllerProperty);
}
/// <summary>
/// Gets or sets a value indicating whether to automatically scroll to end of text.
/// </summary>
public bool AutoScrollToEnd { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="TextController"/> class.
/// </summary>
public TextController()
{
AutoScrollToEnd = true;
}
/// <summary>
/// Sets the text box.
/// </summary>
/// <param name="textBox">The text box.</param>
private void SetTextBox(TextBox textBox)
{
_textBox = textBox;
_textBox.PreviewMouseDown += (_, __) => _isMouseDown = true;
_textBox.PreviewMouseUp += (_, __) => _isMouseDown = false;
}
/// <summary>
/// Appends the specified text.
/// </summary>
/// <param name="text">The text.</param>
public void WriteLine(String text)
{
Write(text + Environment.NewLine);
}
/// <summary>
/// Appends the specified text.
/// </summary>
/// <param name="text">The text.</param>
public void Write(String text)
{
Invoke(() =>
{
_textBox.AppendText(text);
if (AutoScrollToEnd && !_isMouseDown)
{
ScrollToEnd();
}
});
}
/// <summary>
/// Sets the specified text.
/// </summary>
/// <param name="text">The text.</param>
public void Set(String text)
{
Invoke(() =>
{
_textBox.Text = text;
if (AutoScrollToEnd && !_isMouseDown)
{
ScrollToEnd();
}
});
}
/// <summary>
/// Clears the text.
/// </summary>
public void Clear()
{
Invoke(() =>
{
_textBox.Clear();
});
}
/// <summary>
/// Scrolls to the end of the text.
/// </summary>
public void ScrollToEnd()
{
_textBox.ScrollToEnd();
}
/// <summary>
/// Invokes the specified action.
/// </summary>
/// <param name="action">The action.</param>
private void Invoke(Action action)
{
Dispatcher.BeginInvoke(action);
}
}
}