// (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); } } }