Klassenlehrer-Tab: restliche Quick-Wins (responsive Balken, Tagesüberblick-Chart, Tooltips, Status-Symbol)
Balkenbreiten hingen bisher an einer im ViewModel hart codierten Pixelkonstante; Grid.ColumnDefinitions ließ sich dafür nicht binden (AVLN3000, kein Setter bei kompilierten Bindings), deshalb neuer FractionWidthConverter (MultiBinding gegen die gerenderte Breite einer Track-Border statt Grid-Sternspalten). Tagesüberblick zeigt jetzt denselben gestapelten Balken statt vier Einzelzeilen. AbsenceTooltip und TodayUnexcusedPercent waren berechnet aber ungebunden, jetzt sichtbar. Status-Zeilen bekommen zusätzlich zur Farbe ein vorangestelltes Symbol (Barrierefreiheit). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace LehrerApp.Desktop.Converters;
|
||||
|
||||
/// <summary>Multipliziert die gerenderte Breite eines Referenzelements (typischerweise die neutrale
|
||||
/// Track-Leiste eines gestapelten Balkens) mit einem Anteil 0…1. Ersetzt eine im ViewModel hart
|
||||
/// codierte Pixelkonstante (Quick-Win, Nutzer-Feedback) — die Segmentbreite bleibt damit auch
|
||||
/// korrekt, wenn sich die Breite der Seitenspalte in XAML mal ändert, weil sie sich aus der
|
||||
/// tatsächlichen <c>Bounds.Width</c> des Track-Elements ergibt statt aus einer angenommenen
|
||||
/// festen Breite. `Grid.ColumnDefinitions` ließ sich dafür nicht binden (Avalonia bietet dort bei
|
||||
/// kompilierten Bindings keinen Setter — <c>AVLN3000</c>), deshalb MultiBinding auf Pixelbreite
|
||||
/// statt Grid-Sternspalten.</summary>
|
||||
public sealed class FractionWidthConverter : IMultiValueConverter
|
||||
{
|
||||
public static readonly FractionWidthConverter Instance = new();
|
||||
|
||||
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (values is not [double trackWidth, double fraction, ..] || double.IsNaN(trackWidth)) return 0d;
|
||||
return Math.Max(0d, trackWidth * fraction);
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,16 @@ public sealed record ClassTeacherRosterRow(string StudentName, int? ExternKey, b
|
||||
public string ClassRegisterLabel => HasClassRegisterToday ? "Eintrag heute" :
|
||||
HasRecentClassRegisterEntry ? "Eintrag diese Woche" : "";
|
||||
|
||||
/// Quick-Win Barrierefreiheit: der Status wurde bislang ausschließlich über die Farbe des
|
||||
/// linken Balkens/Texts transportiert. Ein kleines vorangestelltes Symbol macht Warnung/Gefahr
|
||||
/// auch ohne verlässliche Farbunterscheidung erkennbar (und beim schnellen Scannen der Liste).
|
||||
public string StatusTextWithGlyph => StatusKind switch
|
||||
{
|
||||
ClassTeacherStatusKind.Danger => $"✕ {StatusText}",
|
||||
ClassTeacherStatusKind.Warning => $"△ {StatusText}",
|
||||
_ => StatusText,
|
||||
};
|
||||
|
||||
/// Kumulierte Fehlzeiten seit Schuljahresbeginn (Nutzer-Feedback: der Heute-Snapshot allein
|
||||
/// sagt für Zeugnis/Attestpflicht wenig aus). <see cref="SchoolDaysElapsed"/> zählt nur
|
||||
/// Werktage, ohne Ferienkalender — eine bewusste Vereinfachung, siehe TODO.md 12.4-Nachtrag.
|
||||
@@ -128,13 +138,22 @@ public sealed record ClassTeacherRosterRow(string StudentName, int? ExternKey, b
|
||||
/// Version zeigte Alerts/Unentschuldigt/Verspätet als drei separate, gleich hohe Balken, obwohl
|
||||
/// Unentschuldigt und Verspätet Teilmengen von Alerts sind — das suggerierte fälschlich drei
|
||||
/// unabhängige Größen). Die drei Segmente sind überschneidungsfrei (Unentschuldigt hat Vorrang
|
||||
/// vor Verspätet, wie bei <see cref="ClassTeacherRosterRow.AttentionRank"/>) und ihre Breiten
|
||||
/// summieren sich exakt zu <see cref="TotalBarWidth"/>.
|
||||
/// vor Verspätet, wie bei <see cref="ClassTeacherRosterRow.AttentionRank"/>).
|
||||
public sealed record ClassTeacherTrendDay(string DayLabel, int AlertCount, int UnexcusedCount,
|
||||
int LateExcusedCount, int ExcusedCount, double UnexcusedBarWidth, double LateExcusedBarWidth,
|
||||
double ExcusedBarWidth)
|
||||
int LateExcusedCount, int ExcusedCount, double UnexcusedFraction, double LateExcusedFraction,
|
||||
double ExcusedFraction)
|
||||
{
|
||||
public double TotalBarWidth => UnexcusedBarWidth + LateExcusedBarWidth + ExcusedBarWidth;
|
||||
/// Anteile 0…1 des höchsten Tages der letzten 7 Schultage statt fester Pixelbreiten
|
||||
/// (Quick-Win, Nutzer-Feedback: die Balkenbreite hing bisher an einer im ViewModel hart
|
||||
/// codierten Pixelkonstante, die mit der tatsächlichen Breite der Seitenspalte in XAML
|
||||
/// synchron gehalten werden musste). Die View multipliziert diese Anteile per MultiBinding
|
||||
/// (<see cref="LehrerApp.Desktop.Converters.FractionWidthConverter"/>) mit der tatsächlich gerenderten Breite
|
||||
/// der Track-Leiste — bleibt damit auch dann korrekt, wenn die Seitenspalte mal eine andere
|
||||
/// Breite bekommt. <c>Grid.ColumnDefinitions</c> ließ sich dafür nicht binden (kein Setter bei
|
||||
/// kompilierten Bindings, AVLN3000), deshalb Pixelbreite statt Grid-Sternspalten.
|
||||
public double TotalFraction => UnexcusedFraction + LateExcusedFraction + ExcusedFraction;
|
||||
public string DetailTooltip =>
|
||||
$"{UnexcusedCount} unentschuldigt · {LateExcusedCount} verspätet · {ExcusedCount} entschuldigt";
|
||||
}
|
||||
public sealed record ClassTeacherPatternNotice(string StudentName, string Message,
|
||||
ClassTeacherStatusKind Kind)
|
||||
@@ -189,6 +208,29 @@ public partial class ClassTeacherOverviewViewModel : ObservableObject
|
||||
public int ExcusedAbsencePercent => Percent(ExcusedAbsenceCount);
|
||||
public int UnexcusedAbsencePercent => Percent(UnexcusedAbsenceCount);
|
||||
|
||||
/// Quick-Win: <see cref="TodayUnexcusedPercent"/> wurde berechnet, aber nirgends gebunden —
|
||||
/// jetzt als zweite Zeile in der "unentschuldigt"-Kennzahlkarte sichtbar.
|
||||
public string TodayUnexcusedSummaryLabel => $"unentschuldigt · {TodayUnexcusedPercent} %";
|
||||
|
||||
/// Beschriftungen für den kompakten Tagesüberblick (Quick-Win: ein gestapelter 100-%-Balken
|
||||
/// statt vier Einzelzeilen mit separater Prozentspalte — Zahl und Anteil jetzt in einer
|
||||
/// Zeile). Die vier Kategorien sind exklusiv und summieren sich exakt zu StudentCount, siehe
|
||||
/// die Herleitung von Present-/Late-/Excused-/UnexcusedAbsenceCount in <see cref="Load"/>.
|
||||
public string PresentSummaryLabel => $"{PresentCount} Anwesend · {PresentPercent} %";
|
||||
public string LateSummaryLabel => $"{LateCount} Verspätet · {LatePercent} %";
|
||||
public string ExcusedAbsenceSummaryLabel => $"{ExcusedAbsenceCount} Entschuldigt · {ExcusedAbsencePercent} %";
|
||||
public string UnexcusedAbsenceSummaryLabel => $"{UnexcusedAbsenceCount} Unentschuldigt · {UnexcusedAbsencePercent} %";
|
||||
/// Anteile 0…1 für den gestapelten Tagesüberblick-Balken (View multipliziert per MultiBinding
|
||||
/// mit der gerenderten Track-Breite, siehe <see cref="ClassTeacherTrendDay.TotalFraction"/>
|
||||
/// für dasselbe Muster beim Trend-Chart). Die vier Kategorien sind exklusiv und summieren sich
|
||||
/// zu 1, da StudentCount == Present + Late + ExcusedAbsence + UnexcusedAbsence.
|
||||
public double PresentFraction => StudentCount == 0 ? 0 : (double)PresentCount / StudentCount;
|
||||
public double LateFraction => StudentCount == 0 ? 0 : (double)LateCount / StudentCount;
|
||||
public double ExcusedAbsenceFraction => StudentCount == 0 ? 0 : (double)ExcusedAbsenceCount / StudentCount;
|
||||
public double UnexcusedAbsenceFraction => StudentCount == 0 ? 0 : (double)UnexcusedAbsenceCount / StudentCount;
|
||||
public string DayOverviewTooltip => $"{PresentCount} anwesend · {LateCount} verspätet · " +
|
||||
$"{ExcusedAbsenceCount} entschuldigt · {UnexcusedAbsenceCount} unentschuldigt";
|
||||
|
||||
public Func<Task>? OnNavigateToSettings { get; set; }
|
||||
public Func<Task>? OnNavigateToWorkload { get; set; }
|
||||
|
||||
@@ -348,7 +390,7 @@ public partial class ClassTeacherOverviewViewModel : ObservableObject
|
||||
foreach (var day in counts)
|
||||
TrendDays.Add(new ClassTeacherTrendDay(day.Date == today ? "Heute" : day.Date.ToString("ddd"),
|
||||
day.Total, day.Unexcused, day.LateExcused, day.Excused,
|
||||
112d * day.Unexcused / max, 112d * day.LateExcused / max, 112d * day.Excused / max));
|
||||
(double)day.Unexcused / max, (double)day.LateExcused / max, (double)day.Excused / max));
|
||||
}
|
||||
|
||||
/// Letzte <paramref name="count"/> Werktage bis einschließlich <paramref name="end"/>, ohne
|
||||
@@ -400,6 +442,12 @@ public partial class ClassTeacherOverviewViewModel : ObservableObject
|
||||
OnPropertyChanged(nameof(TodayUnexcusedPercent)); OnPropertyChanged(nameof(LatePercent));
|
||||
OnPropertyChanged(nameof(PresentPercent)); OnPropertyChanged(nameof(ExcusedAbsencePercent));
|
||||
OnPropertyChanged(nameof(UnexcusedAbsencePercent));
|
||||
OnPropertyChanged(nameof(TodayUnexcusedSummaryLabel));
|
||||
OnPropertyChanged(nameof(PresentSummaryLabel)); OnPropertyChanged(nameof(LateSummaryLabel));
|
||||
OnPropertyChanged(nameof(ExcusedAbsenceSummaryLabel)); OnPropertyChanged(nameof(UnexcusedAbsenceSummaryLabel));
|
||||
OnPropertyChanged(nameof(PresentFraction)); OnPropertyChanged(nameof(LateFraction));
|
||||
OnPropertyChanged(nameof(ExcusedAbsenceFraction)); OnPropertyChanged(nameof(UnexcusedAbsenceFraction));
|
||||
OnPropertyChanged(nameof(DayOverviewTooltip));
|
||||
}
|
||||
private void NotifyRosterState()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.ClassTeacher"
|
||||
xmlns:views="clr-namespace:LehrerApp.Desktop.Views.ClassTeacher"
|
||||
xmlns:conv="clr-namespace:LehrerApp.Desktop.Converters"
|
||||
x:Class="LehrerApp.Desktop.Views.ClassTeacher.ClassTeacherOverviewView"
|
||||
x:DataType="vm:ClassTeacherOverviewViewModel">
|
||||
|
||||
@@ -98,7 +99,8 @@
|
||||
Classes.danger="{Binding IsDangerStatus}"/>
|
||||
<Border Grid.Column="1" Width="28" Height="28" CornerRadius="14"
|
||||
BorderBrush="{DynamicResource AppAvatarBorderBrush}" BorderThickness="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
ToolTip.Tip="{Binding AbsenceTooltip}">
|
||||
<TextBlock Text="{Binding Initials}" FontSize="10"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
@@ -106,7 +108,9 @@
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
<StackPanel Grid.Column="3" VerticalAlignment="Center" Spacing="1"
|
||||
ToolTip.Tip="{Binding YearSummaryTooltip}">
|
||||
<TextBlock Text="{Binding StatusText}" Classes="status"
|
||||
<!-- Quick-Win Barrierefreiheit: Status nicht ausschließlich über Farbe, sondern auch
|
||||
über ein vorangestelltes Symbol bei Warnung/Gefahr (StatusTextWithGlyph). -->
|
||||
<TextBlock Text="{Binding StatusTextWithGlyph}" Classes="status"
|
||||
Classes.info="{Binding IsInfoStatus}"
|
||||
Classes.warning="{Binding IsWarningStatus}"
|
||||
Classes.danger="{Binding IsDangerStatus}"
|
||||
@@ -178,7 +182,7 @@
|
||||
<Grid ColumnDefinitions="36,*">
|
||||
<TextBlock Text="!" FontSize="22" VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource AppStatusDangerBrush}"/>
|
||||
<StackPanel Grid.Column="1"><TextBlock Text="{Binding TodayUnexcusedCount}" FontSize="22" FontWeight="SemiBold"/><TextBlock Text="unentschuldigt" FontSize="11" Opacity="0.6"/></StackPanel>
|
||||
<StackPanel Grid.Column="1"><TextBlock Text="{Binding TodayUnexcusedCount}" FontSize="22" FontWeight="SemiBold"/><TextBlock Text="{Binding TodayUnexcusedSummaryLabel}" FontSize="11" Opacity="0.6"/></StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Grid.Column="3" Classes="metric" Margin="0">
|
||||
@@ -227,10 +231,58 @@
|
||||
<Border Classes="sidePanel">
|
||||
<StackPanel Spacing="9">
|
||||
<TextBlock Text="Tagesüberblick" FontSize="14" FontWeight="SemiBold"/>
|
||||
<Grid ColumnDefinitions="10,*,Auto,40"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill"/><TextBlock Grid.Column="1" Text="Anwesend" FontSize="12"/><TextBlock Grid.Column="2" Text="{Binding PresentCount}"/><TextBlock Grid.Column="3" Text="{Binding PresentPercent, StringFormat='{}{0} %'}" Opacity="0.6" HorizontalAlignment="Right"/></Grid>
|
||||
<Grid ColumnDefinitions="10,*,Auto,40"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill warning"/><TextBlock Grid.Column="1" Text="Verspätet" FontSize="12"/><TextBlock Grid.Column="2" Text="{Binding LateCount}"/><TextBlock Grid.Column="3" Text="{Binding LatePercent, StringFormat='{}{0} %'}" Opacity="0.6" HorizontalAlignment="Right"/></Grid>
|
||||
<Grid ColumnDefinitions="10,*,Auto,40"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill info"/><TextBlock Grid.Column="1" Text="Fehlzeit · entschuldigt" FontSize="12"/><TextBlock Grid.Column="2" Text="{Binding ExcusedAbsenceCount}"/><TextBlock Grid.Column="3" Text="{Binding ExcusedAbsencePercent, StringFormat='{}{0} %'}" Opacity="0.6" HorizontalAlignment="Right"/></Grid>
|
||||
<Grid ColumnDefinitions="10,*,Auto,40"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill danger"/><TextBlock Grid.Column="1" Text="Fehlzeit · unentschuldigt" FontSize="12"/><TextBlock Grid.Column="2" Text="{Binding UnexcusedAbsenceCount}"/><TextBlock Grid.Column="3" Text="{Binding UnexcusedAbsencePercent, StringFormat='{}{0} %'}" Opacity="0.6" HorizontalAlignment="Right"/></Grid>
|
||||
<!-- Quick-Win: ein gestapelter 100-%-Balken statt vier Einzelzeilen mit
|
||||
separater Prozentspalte — Verteilung auf einen Blick statt aus vier
|
||||
Prozentzahlen erschlossen. Jedes Segment multipliziert per MultiBinding
|
||||
die gerenderte Breite der Track-Leiste (x:Name="DayOverviewTrack") mit
|
||||
seinem Anteil 0…1 (FractionWidthConverter) — bleibt dadurch korrekt, egal
|
||||
wie breit die Seitenspalte in XAML gerade ist. -->
|
||||
<Grid Height="10" ToolTip.Tip="{Binding DayOverviewTooltip}">
|
||||
<Border x:Name="DayOverviewTrack" Background="{DynamicResource AppTrackBackgroundBrush}"
|
||||
CornerRadius="5"/>
|
||||
<Border CornerRadius="5" ClipToBounds="True" HorizontalAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Classes="statusFill">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="DayOverviewTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="PresentFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
<Border Classes="statusFill warning">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="DayOverviewTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="LateFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
<Border Classes="statusFill info">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="DayOverviewTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="ExcusedAbsenceFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
<Border Classes="statusFill danger">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="DayOverviewTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="UnexcusedAbsenceFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
<StackPanel Spacing="5">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill"/><TextBlock Text="{Binding PresentSummaryLabel}" FontSize="12"/></StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill warning"/><TextBlock Text="{Binding LateSummaryLabel}" FontSize="12"/></StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill info"/><TextBlock Text="{Binding ExcusedAbsenceSummaryLabel}" FontSize="12"/></StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6"><Border Width="7" Height="7" CornerRadius="4" Classes="statusFill danger"/><TextBlock Text="{Binding UnexcusedAbsenceSummaryLabel}" FontSize="12"/></StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
@@ -242,17 +294,50 @@
|
||||
<DataTemplate x:DataType="vm:ClassTeacherTrendDay">
|
||||
<Grid ColumnDefinitions="42,*,24" Margin="0,2">
|
||||
<TextBlock Text="{Binding DayLabel}" FontSize="11" Opacity="0.6" VerticalAlignment="Center"/>
|
||||
<Grid Grid.Column="1" Height="8" VerticalAlignment="Center">
|
||||
<Border Background="{DynamicResource AppTrackBackgroundBrush}" CornerRadius="4"/>
|
||||
<Grid Grid.Column="1" Height="8" VerticalAlignment="Center"
|
||||
ToolTip.Tip="{Binding DetailTooltip}">
|
||||
<Border x:Name="TrendTrack" Background="{DynamicResource AppTrackBackgroundBrush}"
|
||||
CornerRadius="4"/>
|
||||
<!-- Gestapelter Balken: drei sich nicht überschneidende Segmente
|
||||
(siehe ClassTeacherTrendDay), gemeinsam auf CornerRadius
|
||||
zugeschnitten statt jedes Segment einzeln abzurunden. -->
|
||||
<Border Width="{Binding TotalBarWidth}" HorizontalAlignment="Left"
|
||||
CornerRadius="4" ClipToBounds="True">
|
||||
(siehe ClassTeacherTrendDay). Jedes Segment multipliziert per
|
||||
MultiBinding die gerenderte Breite von "TrendTrack" mit seinem
|
||||
Anteil 0…1 (FractionWidthConverter) — bleibt damit auch dann
|
||||
korrekt proportional, wenn die Seitenspalte in XAML mal eine
|
||||
andere Breite bekommt. Der äußere Wrapper ist auf CornerRadius
|
||||
zugeschnitten, damit nur die äußeren Kanten rund sind, nicht
|
||||
jedes Segment einzeln. -->
|
||||
<Border CornerRadius="4" ClipToBounds="True" HorizontalAlignment="Left">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="TrendTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="TotalFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Width="{Binding UnexcusedBarWidth}" Classes="statusFill danger"/>
|
||||
<Border Width="{Binding LateExcusedBarWidth}" Classes="statusFill warning"/>
|
||||
<Border Width="{Binding ExcusedBarWidth}" Classes="statusFill info"/>
|
||||
<Border Classes="statusFill danger">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="TrendTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="UnexcusedFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
<Border Classes="statusFill warning">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="TrendTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="LateExcusedFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
<Border Classes="statusFill info">
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{x:Static conv:FractionWidthConverter.Instance}">
|
||||
<Binding ElementName="TrendTrack" Path="Bounds.Width"/>
|
||||
<Binding Path="ExcusedFraction"/>
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
Reference in New Issue
Block a user