// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
using System;
using System.ComponentModel;
using Avalonia.Layout;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Controls.Documents;
namespace Avalonia.Controls
{
///
/// Represents a column that hosts textual content in its cells.
///
public class DataGridTextColumn : DataGridBoundColumn
{
///
/// Initializes a new instance of the class.
///
public DataGridTextColumn()
{
BindingTarget = TextBox.TextProperty;
}
///
/// Identifies the FontFamily dependency property.
///
public static readonly AttachedProperty FontFamilyProperty =
TextElement.FontFamilyProperty.AddOwner();
///
/// Gets or sets the font name.
///
public FontFamily FontFamily
{
get => GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
}
///
/// Identifies the FontSize dependency property.
///
public static readonly AttachedProperty FontSizeProperty =
TextElement.FontSizeProperty.AddOwner();
///
/// Gets or sets the font size.
///
// Use DefaultValue here so undo in the Designer will set this to NaN
[DefaultValue(double.NaN)]
public double FontSize
{
get => GetValue(FontSizeProperty);
set => SetValue(FontSizeProperty, value);
}
///
/// Identifies the FontStyle dependency property.
///
public static readonly AttachedProperty FontStyleProperty =
TextElement.FontStyleProperty.AddOwner();
///
/// Gets or sets the font style.
///
public FontStyle FontStyle
{
get => GetValue(FontStyleProperty);
set => SetValue(FontStyleProperty, value);
}
///
/// Identifies the FontWeight dependency property.
///
public static readonly AttachedProperty FontWeightProperty =
TextElement.FontWeightProperty.AddOwner();
///
/// Gets or sets the font weight or thickness.
///
public FontWeight FontWeight
{
get => GetValue(FontWeightProperty);
set => SetValue(FontWeightProperty, value);
}
///
/// Identifies the FontStretch dependency property.
///
public static readonly AttachedProperty FontStretchProperty =
TextElement.FontStretchProperty.AddOwner();
///
/// Gets or sets the font weight or thickness.
///
public FontStretch FontStretch
{
get => GetValue(FontStretchProperty);
set => SetValue(FontStretchProperty, value);
}
///
/// Identifies the Foreground dependency property.
///
public static readonly AttachedProperty ForegroundProperty =
TextElement.ForegroundProperty.AddOwner();
///
/// Gets or sets a brush that describes the foreground of the column cells.
///
public IBrush Foreground
{
get => GetValue(ForegroundProperty);
set => SetValue(ForegroundProperty, value);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == FontFamilyProperty
|| change.Property == FontSizeProperty
|| change.Property == FontStyleProperty
|| change.Property == FontWeightProperty
|| change.Property == ForegroundProperty)
{
NotifyPropertyChanged(change.Property.Name);
}
}
///
/// Causes the column cell being edited to revert to the specified value.
///
/// The element that the column displays for a cell in editing mode.
/// The previous, unedited value in the cell being edited.
protected override void CancelCellEdit(IControl editingElement, object uneditedValue)
{
if (editingElement is TextBox textBox)
{
string uneditedString = uneditedValue as string;
textBox.Text = uneditedString ?? string.Empty;
}
}
///
/// Gets a control that is bound to the column's property value.
///
/// The cell that will contain the generated element.
/// The data item represented by the row that contains the intended cell.
/// A new control that is bound to the column's property value.
protected override IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem)
{
var textBox = new TextBox
{
VerticalAlignment = VerticalAlignment.Stretch,
Background = new SolidColorBrush(Colors.Transparent)
};
SyncProperties(textBox);
return textBox;
}
///
/// Gets a read-only element that is bound to the column's property value.
///
/// The cell that will contain the generated element.
/// The data item represented by the row that contains the intended cell.
/// A new, read-only element that is bound to the column's property value.
protected override IControl GenerateElement(DataGridCell cell, object dataItem)
{
TextBlock textBlockElement = new TextBlock
{
Name = "CellTextBlock"
};
SyncProperties(textBlockElement);
if (Binding != null)
{
textBlockElement.Bind(TextBlock.TextProperty, Binding);
}
return textBlockElement;
}
///
/// Called when the cell in the column enters editing mode.
///
/// The element that the column displays for a cell in editing mode.
/// Information about the user gesture that is causing a cell to enter editing mode.
/// The unedited value.
protected override object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs)
{
if (editingElement is TextBox textBox)
{
string uneditedText = textBox.Text ?? String.Empty;
int len = uneditedText.Length;
if (editingEventArgs is KeyEventArgs keyEventArgs && keyEventArgs.Key == Key.F2)
{
// Put caret at the end of the text
textBox.SelectionStart = len;
textBox.SelectionEnd = len;
}
else
{
// Select all text
textBox.SelectionStart = 0;
textBox.SelectionEnd = len;
textBox.CaretIndex = len;
}
return uneditedText;
}
return string.Empty;
}
///
/// Called by the DataGrid control when this column asks for its elements to be
/// updated, because a property changed.
///
protected internal override void RefreshCellContent(IControl element, string propertyName)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
if (element is AvaloniaObject content)
{
if (propertyName == nameof(FontFamily))
{
DataGridHelper.SyncColumnProperty(this, content, FontFamilyProperty);
}
else if (propertyName == nameof(FontSize))
{
DataGridHelper.SyncColumnProperty(this, content, FontSizeProperty);
}
else if (propertyName == nameof(FontStyle))
{
DataGridHelper.SyncColumnProperty(this, content, FontStyleProperty);
}
else if (propertyName == nameof(FontWeight))
{
DataGridHelper.SyncColumnProperty(this, content, FontWeightProperty);
}
else if (propertyName == nameof(Foreground))
{
DataGridHelper.SyncColumnProperty(this, content, ForegroundProperty);
}
}
else
{
throw DataGridError.DataGrid.ValueIsNotAnInstanceOf("element", typeof(AvaloniaObject));
}
}
private void SyncProperties(AvaloniaObject content)
{
DataGridHelper.SyncColumnProperty(this, content, FontFamilyProperty);
DataGridHelper.SyncColumnProperty(this, content, FontSizeProperty);
DataGridHelper.SyncColumnProperty(this, content, FontStyleProperty);
DataGridHelper.SyncColumnProperty(this, content, FontWeightProperty);
DataGridHelper.SyncColumnProperty(this, content, ForegroundProperty);
}
}
}