[#20][#80] MemberAdminWindow: Update business share status bar tool tip
Test / Run tests (push) Successful in 2m1s

This commit is contained in:
2026-07-06 15:35:05 +02:00
parent 000117dc67
commit 76da392f5f
7 changed files with 174 additions and 102 deletions
+26
View File
@@ -4,11 +4,14 @@ using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.IO.Hashing;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace Elwig.Helpers {
public static partial class Extensions {
@@ -145,5 +148,28 @@ namespace Elwig.Helpers {
}
return [.. list];
}
public static IEnumerable<T> Join<T>(this IEnumerable<T> src, Func<T> separatorFactory) {
var srcArr = src.ToArray();
for (int i = 0; i < srcArr.Length; i++) {
yield return srcArr[i];
if (i < srcArr.Length - 1) {
yield return separatorFactory();
}
}
}
public static void AddToolTipCell(this Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
var tb = new TextBlock() {
Text = text,
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
Margin = new(0, 12 * row, 0, 0),
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
};
tb.SetValue(Grid.ColumnProperty, col);
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
grid.Children.Add(tb);
}
}
}
+7 -19
View File
@@ -158,25 +158,13 @@ namespace Elwig.Services {
});
}
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
var tb = new TextBlock() {
Text = text,
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
Margin = new(0, 12 * row, 0, 0),
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
};
tb.SetValue(Grid.ColumnProperty, col);
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
grid.Children.Add(tb);
}
private static void AddToolTipRow(Grid grid, int row, string? h1, string? h2, int area, int? min, int? max) {
var bold = h2 == null;
if (h1 != null) AddToolTipCell(grid, h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) AddToolTipCell(grid, h2 + ":", row, 1, 1, bold);
AddToolTipCell(grid, $"{area:N0} m²", row, 2, 1, bold, true);
AddToolTipCell(grid, min == null ? "" : $"{min:N0} kg", row, 3, 1, bold, true);
AddToolTipCell(grid, max == null ? "" : $"{max:N0} kg", row, 4, 1, bold, true);
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, bold: bold);
grid.AddToolTipCell($"{area:N0} m²", row, 2, bold: bold, alignRight: true);
grid.AddToolTipCell(min == null ? "" : $"{min:N0} kg", row, 3, bold: bold, alignRight: true);
grid.AddToolTipCell(max == null ? "" : $"{max:N0} kg", row, 4, bold: bold, alignRight: true);
}
public static async Task<(string, (string?, string?, int, int?, int?)[])> GenerateToolTipData(IQueryable<AreaCom> areaComs, int maxKgPerHa) {
@@ -255,8 +243,8 @@ namespace Elwig.Services {
grid.ColumnDefinitions.Add(new() { Width = new(80) });
grid.ColumnDefinitions.Add(new() { Width = new(80) });
grid.ColumnDefinitions.Add(new() { Width = new(80) });
AddToolTipCell(grid, "Lieferpflicht", 0, 3, 1, false, false, true);
AddToolTipCell(grid, "Lieferrecht", 0, 4, 1, false, false, true);
grid.AddToolTipCell("Lieferpflicht", 0, 3, alignCenter: true);
grid.AddToolTipCell("Lieferrecht", 0, 4, 1, alignCenter: true);
int rowNum = 1;
foreach (var row in data) {
if (rowNum == 2 || (rowNum != 1 && row.Item1 != null)) rowNum++;
+5 -17
View File
@@ -276,27 +276,15 @@ namespace Elwig.Services {
}
}
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
var tb = new TextBlock() {
Text = text,
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
Margin = new(0, 12 * row, 0, 0),
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
};
tb.SetValue(Grid.ColumnProperty, col);
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
grid.Children.Add(tb);
}
private static void AddToolTipRow(Grid grid, int row, string? h1, string? h2, int weight, int? total1, int total2) {
var bold = h2 == null;
if (h1 != null) AddToolTipCell(grid, h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) AddToolTipCell(grid, h2 + ":", row, 1, 1, bold);
AddToolTipCell(grid, $"{weight:N0} kg", row, 2, 1, bold, true);
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, 1, bold);
grid.AddToolTipCell($"{weight:N0} kg", row, 2, bold: bold, alignRight: true);
if (total1 != null && total1 != 0)
AddToolTipCell(grid, $"{weight * 100.0 / total1:N1} %", row, 3, 1, bold, true);
grid.AddToolTipCell($"{weight * 100.0 / total1:N1} %", row, 3, bold: bold, alignRight: true);
if (total2 != 0)
AddToolTipCell(grid, $"{weight * 100.0 / total2:N1} %", row, 4, 1, bold, true);
grid.AddToolTipCell($"{weight * 100.0 / total2:N1} %", row, 4, bold: bold, alignRight: true);
}
public static async Task<(string Text, (string?, string?, int, int?, int)[] Grid)> GenerateToolTipData(IQueryable<DeliveryAncmt> deliveryAncmts) {
+13 -25
View File
@@ -940,36 +940,24 @@ namespace Elwig.Services {
}
}
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
var tb = new TextBlock() {
Text = text,
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
Margin = new(0, 12 * row, 0, 0),
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
};
tb.SetValue(Grid.ColumnProperty, col);
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
grid.Children.Add(tb);
}
private static void AddWeightToolTipRow(Grid grid, int row, string? h1, string? h2, int weight, int? total1, int total2) {
var bold = h2 == null;
if (h1 != null) AddToolTipCell(grid, h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) AddToolTipCell(grid, h2 + ":", row, 1, 1, bold);
AddToolTipCell(grid, $"{weight:N0} kg", row, 2, 1, bold, true);
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, 1, bold);
grid.AddToolTipCell($"{weight:N0} kg", row, 2, bold: bold, alignRight: true);
if (total1 != null && total1 != 0)
AddToolTipCell(grid, $"{weight * 100.0 / total1:N1} %", row, 3, 1, bold, true);
grid.AddToolTipCell($"{weight * 100.0 / total1:N1} %", row, 3, bold: bold, alignRight: true);
if (total2 != 0)
AddToolTipCell(grid, $"{weight * 100.0 / total2:N1} %", row, 4, 1, bold, true);
grid.AddToolTipCell($"{weight * 100.0 / total2:N1} %", row, 4, bold: bold, alignRight: true);
}
private static void AddGradationToolTipRow(Grid grid, int row, string? h1, string? h2, double min, double avg, double max) {
var bold = h2 == null;
if (h1 != null) AddToolTipCell(grid, h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) AddToolTipCell(grid, h2 + ":", row, 1, 1, bold);
AddToolTipCell(grid, $"{min:N1}°", row, 2, 1, bold, true);
AddToolTipCell(grid, $"{avg:N1}°", row, 3, 1, bold, true);
AddToolTipCell(grid, $"{max:N1}°", row, 4, 1, bold, true);
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, bold: bold);
grid.AddToolTipCell($"{min:N1}°", row, 2, bold: bold, alignRight: true);
grid.AddToolTipCell($"{avg:N1}°", row, 3, bold: bold, alignRight: true);
grid.AddToolTipCell($"{max:N1}°", row, 4, bold: bold, alignRight: true);
}
public static async Task<(string WeightText, (string?, string?, int, int?, int)[] WeightGrid, string GradationText, (string?, string?, double, double, double)[] GradationGrid)> GenerateToolTipData(IQueryable<DeliveryPart> deliveryParts) {
@@ -1098,9 +1086,9 @@ namespace Elwig.Services {
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
AddToolTipCell(gGrid, "Min.", 0, 2, 1, false, false, true);
AddToolTipCell(gGrid, "⌀", 0, 3, 1, false, false, true);
AddToolTipCell(gGrid, "Max.", 0, 4, 1, false, false, true);
gGrid.AddToolTipCell("Min.", 0, 2, alignCenter: true);
gGrid.AddToolTipCell("⌀", 0, 3, alignCenter: true);
gGrid.AddToolTipCell("Max.", 0, 4, alignCenter: true);
rowNum = 1;
foreach (var row in gradationData) {
if (rowNum != 1 && row.Item2 == null) rowNum++;
+2 -3
View File
@@ -6,6 +6,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace Elwig.ViewModels {
public partial class MemberAdminViewModel : ObservableObject {
@@ -200,9 +201,7 @@ namespace Elwig.ViewModels {
[ObservableProperty]
private string? _statusMembersToolTip;
[ObservableProperty]
private string _statusBusinessShares = "-";
[ObservableProperty]
private string? _statusBusinessSharesToolTip;
private TextBlock? _statusBusinessShares;
[ObservableProperty]
private string _statusDeliveriesLastSeason = "-";
[ObservableProperty]
+2 -6
View File
@@ -723,7 +723,7 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
@@ -740,11 +740,7 @@
</TextBlock>
</StatusBarItem>
<Separator Grid.Column="1"/>
<StatusBarItem Grid.Column="2">
<TextBlock ToolTip="{Binding StatusBusinessSharesToolTip}">
Geschäftsanteile: <Run Text="{Binding StatusBusinessShares}"/>
</TextBlock>
</StatusBarItem>
<StatusBarItem Grid.Column="2" Content="{Binding StatusBusinessShares}"/>
<Separator Grid.Column="3"/>
<StatusBarItem Grid.Column="4">
<TextBlock ToolTip="{Binding StatusAreaCommitmentToolTip}">
+119 -32
View File
@@ -1,20 +1,21 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Elwig.Dialogs;
using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Models.Entities;
using System.Threading.Tasks;
using Elwig.Documents;
using System.Diagnostics;
using Elwig.Dialogs;
using Elwig.Services;
using Elwig.ViewModels;
using System.Windows.Data;
using System.Windows.Media;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace Elwig.Windows {
public partial class MemberAdminWindow : AdministrationWindow {
@@ -146,7 +147,7 @@ namespace Elwig.Windows {
var cursor = Mouse.OverrideCursor != null;
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
var query = (vm.SearchQuery, vm.ShowOnlyActiveMembers);
var (members, totalMemberCount, totalBusinessShares) = await Task.Run(async () => {
var (members, stat) = await Task.Run(async () => {
using var ctx = new AppDbContext();
var (_, memberQuery, filter) = await vm.GetFilters(ctx);
var members = await memberQuery
@@ -173,10 +174,17 @@ namespace Elwig.Windows {
.ThenBy(m => m.MgNr)];
}
var totalMemberCount = await ctx.Members.CountAsync();
var totalBusinessShares = await ctx.Members.SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant);
var stat = (await ctx.Members.GroupBy(m => 1).Select(g => new {
Count = g.Count(),
Shares = g.Sum(m => m.Shares),
SharesRed = g.Sum(m => m.SharesRed),
SharesWhite = g.Sum(m => m.SharesWhite),
SharesDormant = g.Sum(m => m.SharesDormant),
SharesTotal = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant),
SharesActive = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite),
}).ToListAsync()).Select(g => (g.Count, g.Shares, g.SharesRed, g.SharesWhite, g.SharesDormant, g.SharesTotal, g.SharesActive)).ToList();
return (members, totalMemberCount, totalBusinessShares);
return (members, stat[0]);
});
if (!cursor) Mouse.OverrideCursor = null;
if (query != (ViewModel.SearchQuery, ViewModel.ShowOnlyActiveMembers)) return;
@@ -186,8 +194,39 @@ namespace Elwig.Windows {
if (updateSort && MemberList.SelectedItem != null)
MemberList.ScrollIntoView(MemberList.SelectedItem);
ViewModel.StatusMembers = $"{members.Count:N0} ({totalMemberCount:N0})";
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0} ({totalBusinessShares:N0})";
ViewModel.StatusMembers = $"{members.Count:N0} ({stat.Count:N0})";
var sA = members.Sum(m => m.Shares);
var rA = members.Sum(m => m.SharesRed);
var wA = members.Sum(m => m.SharesWhite);
var dA = members.Sum(m => m.SharesDormant);
List<(int Count, Brush? Color)> a = [];
if (sA > 0) a.Add((sA, null));
if (rA > 0) a.Add((rA, Brushes.DarkRed));
if (wA > 0) a.Add((wA, Brushes.DarkGreen));
if (a.Count == 0) a.Add((0, null));
if (dA > 0) a.Add((dA, null));
List<(int Count, Brush? Color)> b = [];
if (stat.Shares > 0) b.Add((stat.Shares, null));
if (stat.SharesRed > 0) b.Add((stat.SharesRed, Brushes.DarkRed));
if (stat.SharesWhite > 0) b.Add((stat.SharesWhite, Brushes.DarkGreen));
if (a.Count == 0) b.Add((0, null));
if (stat.SharesDormant > 0) b.Add((stat.SharesDormant, null));
Run[] inlines = [
new("Geschäftsanteile: "),
.. a.Select(i => new Run($"{i.Count:N0}") { Foreground = i.Color ?? Brushes.Black }).Join(() => new("+")),
new(" ("),
.. b.Select(i => new Run($"{i.Count:N0}") { Foreground = i.Color ?? Brushes.Black }).Join(() => new("+")),
new(")")
];
if (ViewModel.StatusBusinessShares == null) {
ViewModel.StatusBusinessShares = new();
} else {
ViewModel.StatusBusinessShares.Inlines.Clear();
}
ViewModel.StatusBusinessShares.Inlines.AddRange(inlines);
}
private void RefreshInputs(bool validate = false) {
@@ -233,7 +272,7 @@ namespace Elwig.Windows {
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync());
var font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets");
var font = new FontFamily("Segoe MDL2 Assets");
MenuItem? temp = null;
var seasons = await ctx.Seasons.Include(s => s.PaymentVariants).OrderByDescending(s => s.Year).ToListAsync();
Menu_DeliveryConfirmation.Items.Clear();
@@ -310,10 +349,21 @@ namespace Elwig.Windows {
await RefreshList();
var stat = await ctx.Members.GroupBy(m => m.IsActive).Select(g => new {
IsActive = g.Key,
Count = g.Count(),
Shares = g.Sum(m => m.Shares),
SharesRed = g.Sum(m => m.SharesRed),
SharesWhite = g.Sum(m => m.SharesWhite),
SharesDormant = g.Sum(m => m.SharesDormant),
SharesTotal = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant),
SharesActive = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite),
}).ToDictionaryAsync(g => g.IsActive);
var (s1, s2) = ('\u2007', '\u202f');
var mA = $"{await ctx.Members.CountAsync(m => m.IsActive):N0}";
var mI = $"{await ctx.Members.CountAsync(m => !m.IsActive):N0}";
var mT = $"{await ctx.Members.CountAsync():N0}";
var mA = $"{stat.GetValueOrDefault(true)?.Count ?? 0:N0}";
var mI = $"{stat.GetValueOrDefault(false)?.Count ?? 0:N0}";
var mT = $"{stat.Sum(g => g.Value.Count):N0}";
var mM = Math.Max(mA.Length, Math.Max(mI.Length, mT.Length));
var mS = mM > 3;
if (mS) mM--;
@@ -322,16 +372,53 @@ namespace Elwig.Windows {
$"{new string(s1, Math.Max(0, mM - mI.Length))}{(mS && mI.Length < 4 ? s2 : "")}{mI} nicht aktive Mitglieder\n" +
$"{new string(s1, Math.Max(0, mM - mT.Length))}{(mS && mT.Length < 4 ? s2 : "")}{mT} Mitglieder gesamt";
var bA = $"{await ctx.Members.Where(m => m.IsActive).SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0}";
var bI = $"{await ctx.Members.Where(m => !m.IsActive).SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0}";
var bT = $"{await ctx.Members.SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0}";
var bM = Math.Max(bA.Length, Math.Max(bI.Length, bT.Length));
var bS = bM > 3;
if (bS) bM--;
ViewModel.StatusBusinessSharesToolTip =
$"{new string(s1, Math.Max(0, bM - bA.Length))}{(bS && bA.Length < 4 ? s2 : "")}{bA} Geschäftsanteile von aktiven Mitgliedern\n" +
$"{new string(s1, Math.Max(0, bM - bI.Length))}{(bS && bI.Length < 4 ? s2 : "")}{bI} Geschäftsanteile von nicht aktiven Mitgliedern\n" +
$"{new string(s1, Math.Max(0, bM - bT.Length))}{(bS && bT.Length < 4 ? s2 : "")}{bT} Geschäftsanteile gesamt";
var grid = new Grid();
grid.ColumnDefinitions.Add(new() { Width = new(100) });
grid.AddToolTipCell("Geschäftsanteile:", 0, 0, bold: true);
grid.AddToolTipCell("Aktive Mitglieder", 1, 0);
grid.AddToolTipCell("Nicht aktive Mg.", 2, 0);
grid.AddToolTipCell("Alle Mitglieder", 3, 0, bold: true);
if (App.Client.HasRedWhite) {
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.AddToolTipCell("rot", 0, 1, alignRight: true);
grid.AddToolTipCell("weiß", 0, 2, alignRight: true);
grid.AddToolTipCell("ruhend", 0, 3, alignRight: true);
grid.AddToolTipCell("gesamt", 0, 4, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesRed ?? 0:N0}", 1, 1, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesWhite ?? 0:N0}", 1, 2, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesDormant ?? 0:N0}", 1, 3, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesTotal ?? 0:N0}", 1, 4, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesRed ?? 0:N0}", 2, 1, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesWhite ?? 0:N0}", 2, 2, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesDormant ?? 0:N0}", 2, 3, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesTotal ?? 0:N0}", 2, 4, alignRight: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesRed):N0}", 3, 1, alignRight: true, bold: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesWhite):N0}", 3, 2, alignRight: true, bold: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesDormant):N0}", 3, 3, alignRight: true, bold: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesTotal):N0}", 3, 4, alignRight: true, bold: true);
} else {
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.ColumnDefinitions.Add(new() { Width = new(50) });
grid.AddToolTipCell("normal", 0, 1, alignRight: true);
grid.AddToolTipCell("ruhend", 0, 2, alignRight: true);
grid.AddToolTipCell("gesamt", 0, 3, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.Shares ?? 0:N0}", 1, 1, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesDormant ?? 0:N0}", 1, 2, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesTotal ?? 0:N0}", 1, 3, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.Shares ?? 0:N0}", 2, 1, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesDormant ?? 0:N0}", 2, 2, alignRight: true);
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesTotal ?? 0:N0}", 2, 3, alignRight: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.Shares):N0}", 3, 1, alignRight: true, bold: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesDormant):N0}", 3, 2, alignRight: true, bold: true);
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesTotal):N0}", 3, 3, alignRight: true, bold: true);
}
ViewModel.StatusBusinessShares?.ToolTip = grid;
}
private void SetPhoneNrInputVisible(int nr, bool visible, int? position = null) {