Как в DataGridTextColumn реализовать переход на экспоненциальную запись, когда не хватает места для полного отображения числа. Желаемый эффект:
Есть идея использовать конвертор, и вызывать его всякий раз при изменении ширины колонки. В конверторе использовать StringFormat. Возникают дополнительные вопросы: на какое событие нужно подписаться которое бы отслеживало изменение размера колонки? как определять сколько символов влезает в ячейку, чтобы знать сколько символов отобразить после запятой и до E? P.S. Что-то подобное делает свойство TextTrimming="CharacterEllipsis" у TextBlock. при нехватке места для отображения часть символов заменяется многоточием. Если узнать каким способом TextBlock определяет что ему не хватает места отобразить текст, то может и получиться решить данный вопрос.
Ответ По идее, для этого можно приспособить UserControl и немного code-behind. Для измерения ширины текста без отображения подойдёт класс FormattedText. Вот простой набросок: Контрол:
Code-behind: public partial class DoubleWidthFitControl : UserControl { public DoubleWidthFitControl() { InitializeComponent() SizeChanged += (o, args) => Recalc() } #region dp double Value public double Value { get { return (double)GetValue(ValueProperty) } set { SetValue(ValueProperty, value) } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof(double), typeof(DoubleWidthFitControl), new PropertyMetadata(0.0, (o, args) => ((DoubleWidthFitControl)o).Recalc())) #endregion void Recalc() { var targetWidth = ActualWidth var num = Value string s // у C# 7 есть локальные функции, вау! bool CheckLength(string format) { s = num.ToString(format) return Measure(s) <= targetWidth }<br> if (CheckLength("F") || CheckLength("G")) { Target.Text = s return } int i for (i = 0 CheckLength($"E{i}") i++) /**/ if (i == 0) Target.Text = "###" else Target.Text = num.ToString($"E{i - 1}") } double Measure(string s) { TextBlock tb = Target var formattedText = new FormattedText( s, CultureInfo.CurrentCulture, tb.FlowDirection, new Typeface(tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), tb.FontSize, Brushes.Black) return formattedText.Width } } Использовать просто:
Результат:
Есть хороший потенциал для дальнейшей оптимизации. Например, при данной строке и шрифте можно один раз подсчитать и запомнить варианты отображения с их размерами, и просто подбирать наибольший вписывающийся.