feat: redesign Pump page with Fluent card layout, bottom snackbar, and RPM chart
- Replace sub-nav + HiddenTabsTabControl with 3-column Fluent card layout: PumpCommandsCard (vertical ME/FBKW/PreIn sliders) + DfiCalibrationCard / PumpLiveDataCard (KPI tiles + RPM rolling chart + redesigned status bytes) / PumpIdentificationCard + DtcCard - Add PumpTopStripView: pump selector, model badge, CAN + K-Line chips - Move immobilizer unlock to MainWindow bottom snackbar (UnlockSnackbarView): auto-close on success after 3 s, persist on failure with manual Dismiss - Redesign StatusDisplayView to 2×8 rounded 28px tiles with bit index + tooltip - Add NullToVisibilityConverter; add SnackbarShell, PumpCard, and related styles - Delete obsolete views: UnlockProgressDialog, UnlockPanelView, PumpIdentificationPanelView, PumpLiveDataView, DfiManageView, DtcListView, PumpControlView - PumpPageViewModel: remove PumpSubPage enum, add RpmChart wired to Root.PumpRpm Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,138 +0,0 @@
|
||||
<Window x:Class="HC_APTBS.Views.Dialogs.UnlockProgressDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
Title="{DynamicResource Dialog.Unlock.Title}"
|
||||
Height="360" Width="340"
|
||||
WindowStyle="None" ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Topmost="True"
|
||||
Background="#FF2B2929"
|
||||
MouseLeftButtonDown="OnMouseDrag"
|
||||
Closing="OnWindowClosing">
|
||||
|
||||
<Window.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="210"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Unlock type label -->
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding UnlockTypeLabel, Mode=OneWay}"
|
||||
FontSize="14" Foreground="#AAAAAA"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,4"/>
|
||||
|
||||
<!-- Progress ring area -->
|
||||
<Grid Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<!-- Background ring -->
|
||||
<Ellipse Width="200" Height="200"
|
||||
Stroke="#4D4D4D" StrokeThickness="10"
|
||||
Fill="Transparent"/>
|
||||
|
||||
<!-- Content inside ring -->
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Dialog.Unlock.Progress}"
|
||||
FontSize="12" Foreground="#888888"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,4"/>
|
||||
|
||||
<!-- Percentage -->
|
||||
<TextBlock FontSize="60" FontFamily="Courier New"
|
||||
Foreground="White" HorizontalAlignment="Center">
|
||||
<TextBlock.Text>
|
||||
<Binding Path="Progress" Mode="OneWay"
|
||||
StringFormat="{}{0}%"/>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
|
||||
<!-- Elapsed time -->
|
||||
<TextBlock Text="{Binding ElapsedTime, Mode=OneWay}"
|
||||
FontSize="16" FontFamily="Courier New"
|
||||
Foreground="#CCCCCC" HorizontalAlignment="Center"
|
||||
Margin="0,2,0,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Phase text -->
|
||||
<TextBlock Grid.Row="2"
|
||||
Text="{Binding PhaseText, Mode=OneWay}"
|
||||
FontSize="16" Foreground="White"
|
||||
HorizontalAlignment="Center" Margin="0,4,0,6"/>
|
||||
|
||||
<!-- Progress bar -->
|
||||
<ProgressBar Grid.Row="3"
|
||||
Value="{Binding Progress, Mode=OneWay}"
|
||||
Minimum="0" Maximum="100"
|
||||
Height="12" Margin="8,0"
|
||||
Foreground="#00EC00" Background="#3D3D3D"/>
|
||||
|
||||
<!-- Result text — overlays the spacer row so it never displaces buttons -->
|
||||
<TextBlock Grid.Row="4"
|
||||
Text="{Binding ResultText, Mode=OneWay}"
|
||||
FontSize="22" FontWeight="Bold"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
Visibility="{Binding IsComplete, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#FF5858"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSuccess}" Value="True">
|
||||
<Setter Property="Foreground" Value="#00EC00"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
|
||||
<!-- Buttons -->
|
||||
<StackPanel Grid.Row="5" Orientation="Horizontal"
|
||||
HorizontalAlignment="Center" Margin="0,8,0,0">
|
||||
<!-- Cancel button -->
|
||||
<Button Content="{DynamicResource Common.Cancel}" Width="90" Height="30"
|
||||
Margin="0,0,12,0"
|
||||
Command="{Binding CancelCommand}"
|
||||
Foreground="White" FontWeight="Bold">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF5858"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Background" Value="#4D4D4D"/>
|
||||
<Setter Property="Foreground" Value="#888888"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
<!-- Close button -->
|
||||
<Button Content="{DynamicResource Common.Close}" Width="90" Height="30"
|
||||
Command="{Binding CloseCommand}"
|
||||
Foreground="White" FontWeight="Bold">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#4D4D4D"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="True">
|
||||
<Setter Property="Background" Value="#337AB7"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Foreground" Value="#888888"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,49 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using HC_APTBS.ViewModels.Dialogs;
|
||||
|
||||
namespace HC_APTBS.Views.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Non-modal window showing immobilizer unlock progress.
|
||||
/// Prevents user-initiated closing until the unlock sequence completes;
|
||||
/// programmatic close via <see cref="ForceClose"/> always succeeds.
|
||||
/// Equivalent to the old <c>WUnlocker</c> window.
|
||||
/// </summary>
|
||||
public partial class UnlockProgressDialog : Window
|
||||
{
|
||||
private bool _forceClose;
|
||||
|
||||
/// <summary>Creates the dialog and wires the ViewModel.</summary>
|
||||
public UnlockProgressDialog(UnlockProgressViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = vm;
|
||||
vm.RequestClose += ForceClose;
|
||||
}
|
||||
|
||||
/// <summary>Closes the window unconditionally (bypasses the completion guard).</summary>
|
||||
public void ForceClose()
|
||||
{
|
||||
_forceClose = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>Allows dragging the borderless window by clicking anywhere.</summary>
|
||||
private void OnMouseDrag(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
DragMove();
|
||||
}
|
||||
|
||||
/// <summary>Prevents user-initiated closing while the unlock sequence is still running.</summary>
|
||||
private void OnWindowClosing(object? sender, CancelEventArgs e)
|
||||
{
|
||||
if (_forceClose) return;
|
||||
|
||||
if (DataContext is UnlockProgressViewModel vm && !vm.IsComplete)
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,262 +4,62 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="clr-namespace:HC_APTBS.Views.UserControls"
|
||||
xmlns:vm="clr-namespace:HC_APTBS.ViewModels.Pages"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="780" d:DesignWidth="1100">
|
||||
d:DesignHeight="900" d:DesignWidth="1400">
|
||||
<!--
|
||||
Pump page — ECU diagnostics and control.
|
||||
DataContext = PumpPageViewModel.
|
||||
|
||||
Layout:
|
||||
- Banner row: K-Line session banner + "no pump selected" banner
|
||||
- Sub-nav (left): Identification / DTCs / LiveData / Adaptation / Unlock
|
||||
- Sub-page content (right): selected sub-section via hidden tabs
|
||||
Layout: top strip (row 0) + 3-column card body (row 1).
|
||||
Col 0 (1*, MinWidth=260): PumpCommandsCard (2*) + DfiCalibrationCard (1*)
|
||||
Col 1 (1.5*): PumpLiveDataCard (fills)
|
||||
Col 2 (1*, MinWidth=280): PumpIdentificationCard (Auto) + DtcCard (*)
|
||||
-->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
|
||||
<!-- Sub-nav item: narrower than the main rail, same accent pattern -->
|
||||
<Style x:Key="SubNavItem" TargetType="ListBoxItem">
|
||||
<Setter Property="Height" Value="44"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBoxItem">
|
||||
<Border x:Name="Root" Background="Transparent">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="Accent" Grid.Column="0" Background="Transparent"/>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Margin="12,0,6,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Root" Property="Background" Value="#ECECEC"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="Root" Property="Background" Value="#E4EEF7"/>
|
||||
<Setter TargetName="Accent" Property="Background" Value="#2196F3"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value="0.35"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SubNavText" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="Foreground" Value="#333"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid Margin="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- banners -->
|
||||
<RowDefinition Height="*"/> <!-- body -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════════
|
||||
Banners: K-Line session + no pump selected
|
||||
══════════════════════════════════════════════════════════════ -->
|
||||
<StackPanel Grid.Row="0">
|
||||
<!-- ── Top status strip ─────────────────────────────────────────────── -->
|
||||
<uc:PumpTopStripView Grid.Row="0"/>
|
||||
|
||||
<!-- K-Line session banner (closed / failed) -->
|
||||
<Border Padding="10,6">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="#FFF3CD"/>
|
||||
<Setter Property="BorderBrush" Value="#FFC107"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsKLineSessionOpen}" Value="True">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsKLineSessionFailed}" Value="True">
|
||||
<Setter Property="Background" Value="#FDECEA"/>
|
||||
<Setter Property="BorderBrush" Value="#D62828"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock FontSize="12" TextWrapping="Wrap">
|
||||
<Run Text="●" FontSize="14"/>
|
||||
<Run Text=" "/>
|
||||
<Run Text="{DynamicResource Pump.KLineClosed}"/>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
|
||||
<!-- No pump selected banner (BoolToVis has no Invert support, so use a DataTrigger style) -->
|
||||
<Border Background="#E3F2FD" BorderBrush="#2196F3" BorderThickness="0,0,0,1"
|
||||
Padding="10,6">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsPumpSelected}" Value="False">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{DynamicResource Pump.NoPumpSelected}"
|
||||
FontSize="12" Foreground="#0D47A1"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════════
|
||||
Body: sub-nav + sub-page content
|
||||
══════════════════════════════════════════════════════════════ -->
|
||||
<!-- ── Body: 3-column card layout ───────────────────────────────────── -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="1*" MinWidth="260"/>
|
||||
<ColumnDefinition Width="1.5*"/>
|
||||
<ColumnDefinition Width="1*" MinWidth="280"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- ── Sub-nav rail ───────────────────────────────────────── -->
|
||||
<Border Grid.Column="0" Background="#F7F7F7"
|
||||
BorderBrush="#DDD" BorderThickness="0,0,1,0">
|
||||
<ListBox SelectedValuePath="Tag" BorderThickness="0"
|
||||
Background="Transparent"
|
||||
ItemContainerStyle="{StaticResource SubNavItem}"
|
||||
SelectedValue="{Binding SelectedSubPage, Mode=TwoWay}">
|
||||
<ListBoxItem Tag="{x:Static vm:PumpSubPage.Identification}">
|
||||
<TextBlock Text="{DynamicResource PumpSub.Identification}"
|
||||
Style="{StaticResource SubNavText}"/>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Tag="{x:Static vm:PumpSubPage.Dtcs}"
|
||||
IsEnabled="{Binding IsPumpSelected}">
|
||||
<TextBlock Text="{DynamicResource PumpSub.Dtcs}"
|
||||
Style="{StaticResource SubNavText}"/>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Tag="{x:Static vm:PumpSubPage.LiveData}"
|
||||
IsEnabled="{Binding IsPumpSelected}">
|
||||
<TextBlock Text="{DynamicResource PumpSub.LiveData}"
|
||||
Style="{StaticResource SubNavText}"/>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Tag="{x:Static vm:PumpSubPage.Adaptation}"
|
||||
IsEnabled="{Binding IsPumpSelected}">
|
||||
<TextBlock Text="{DynamicResource PumpSub.Adaptation}"
|
||||
Style="{StaticResource SubNavText}"/>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Tag="{x:Static vm:PumpSubPage.Unlock}">
|
||||
<ListBoxItem.Style>
|
||||
<Style TargetType="ListBoxItem" BasedOn="{StaticResource SubNavItem}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsUnlockApplicable}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ListBoxItem.Style>
|
||||
<TextBlock Text="{DynamicResource PumpSub.Unlock}"
|
||||
Style="{StaticResource SubNavText}"/>
|
||||
</ListBoxItem>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<!-- Col 0: Commands (top 2*) + Idling Calibration (bottom 1*) -->
|
||||
<Grid Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="2*"/>
|
||||
<RowDefinition Height="1*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- ── Sub-page content ───────────────────────────────────── -->
|
||||
<TabControl Grid.Column="1"
|
||||
Style="{StaticResource HiddenTabsTabControl}"
|
||||
SelectedIndex="{Binding SelectedSubPage, Converter={StaticResource EnumToInt}}">
|
||||
<uc:PumpCommandsCard Grid.Row="0" DataContext="{Binding PumpControl}"/>
|
||||
<uc:DfiCalibrationCard Grid.Row="1" DataContext="{Binding DfiViewModel}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 3a Identification -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<uc:PumpIdentificationPanelView
|
||||
DataContext="{Binding Identification}"/>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<!-- Col 1: Live Data (full height) -->
|
||||
<uc:PumpLiveDataCard Grid.Column="1"/>
|
||||
|
||||
<!-- 3b DTCs -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<uc:DtcListView DataContext="{Binding DtcList}"/>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<!-- Col 2: Identification (Auto) + DTCs (*) -->
|
||||
<Grid Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 3c Live Data — DataContext stays as PumpPageViewModel so
|
||||
the view can reach Root.PumpXxx and StatusDisplay1/2. -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<uc:PumpLiveDataView/>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<!-- 3d Adaptation -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<Border Background="#FAFAFA" BorderBrush="#DDD"
|
||||
BorderThickness="1" CornerRadius="4"
|
||||
Padding="12" Margin="6">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{DynamicResource PumpSub.Adaptation}"
|
||||
FontSize="15" FontWeight="SemiBold"
|
||||
Foreground="#333" Margin="0,0,0,8"/>
|
||||
<uc:DfiManageView DataContext="{Binding DfiViewModel}"/>
|
||||
<Separator Margin="0,10"/>
|
||||
<uc:PumpControlView DataContext="{Binding PumpControl}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<!-- 3e Unlock -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<Grid>
|
||||
<!-- "No active unlock" placeholder — visible when UnlockVm is null -->
|
||||
<Border Background="#F5F5F5" BorderBrush="#CCC"
|
||||
BorderThickness="1" CornerRadius="4"
|
||||
Padding="20" Margin="6"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding UnlockVm}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{DynamicResource Pump.NoUnlockActive}"
|
||||
FontSize="13" Foreground="#666"/>
|
||||
</Border>
|
||||
|
||||
<!-- Active unlock panel — visible when UnlockVm is non-null.
|
||||
DataContext binds to UnlockVm so `{Binding}` inside the
|
||||
style evaluates to the VM instance (or null). -->
|
||||
<uc:UnlockPanelView DataContext="{Binding UnlockVm}">
|
||||
<uc:UnlockPanelView.Style>
|
||||
<Style TargetType="uc:UnlockPanelView">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</uc:UnlockPanelView.Style>
|
||||
</uc:UnlockPanelView>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
</TabControl>
|
||||
<uc:PumpIdentificationCard Grid.Row="0" DataContext="{Binding Identification}"/>
|
||||
<uc:DtcCard Grid.Row="1" DataContext="{Binding DtcList}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
132
Views/UserControls/DfiCalibrationCard.xaml
Normal file
132
Views/UserControls/DfiCalibrationCard.xaml
Normal file
@@ -0,0 +1,132 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.DfiCalibrationCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="260" d:DesignWidth="260">
|
||||
|
||||
<!-- DataContext = DfiManageViewModel (via {Binding DfiViewModel}) -->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Style="{StaticResource PumpCard}">
|
||||
<DockPanel LastChildFill="True">
|
||||
|
||||
<!-- ── Card header ───────────────────────────────────────────── -->
|
||||
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,12">
|
||||
<ui:SymbolIcon DockPanel.Dock="Left" Symbol="Gauge24" FontSize="16"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
|
||||
Margin="0,0,8,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.Dfi.Title}"
|
||||
Style="{StaticResource PumpCardHeader}" Margin="0"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- ── Version selector row ──────────────────────────────────── -->
|
||||
<Grid DockPanel.Dock="Top" Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{DynamicResource Pump.Dfi.Version}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
SelectedIndex="{Binding VersionIndex}"
|
||||
Height="28">
|
||||
<ComboBoxItem Content="V1"/>
|
||||
<ComboBoxItem Content="V2"/>
|
||||
<ComboBoxItem Content="V3"/>
|
||||
<ComboBoxItem Content="V4"/>
|
||||
</ComboBox>
|
||||
<CheckBox Grid.Column="2"
|
||||
IsChecked="{Binding IsAutoMode}"
|
||||
Content="{DynamicResource Dfi.Auto}"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Current DFI readout ───────────────────────────────────── -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
Background="{DynamicResource ControlFillColorSecondaryBrush}"
|
||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||
BorderThickness="1" CornerRadius="6" Padding="12,8"
|
||||
Margin="0,0,0,12">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{DynamicResource Pump.Dfi.Current}"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding CurrentDfi, StringFormat=F2, Mode=OneWay}"
|
||||
FontFamily="Consolas" FontSize="22" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ── Busy indicator ─────────────────────────────────────────── -->
|
||||
<ProgressBar DockPanel.Dock="Top"
|
||||
Value="{Binding ProgressPercent, Mode=OneWay}"
|
||||
Minimum="0" Maximum="100" Height="3"
|
||||
Margin="0,0,0,6"
|
||||
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVis}}"/>
|
||||
|
||||
<!-- ── DFI slider ─────────────────────────────────────────────── -->
|
||||
<Grid DockPanel.Dock="Top" Margin="0,0,0,8">
|
||||
<Slider Value="{Binding SliderRaw}"
|
||||
Minimum="-145" Maximum="145"
|
||||
TickFrequency="5" SmallChange="5" LargeChange="5"
|
||||
IsSnapToTickEnabled="True" TickPlacement="BottomRight"
|
||||
Margin="0,0,0,4" VerticalAlignment="Center"/>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="-1.45"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
||||
FontSize="10" Foreground="{DynamicResource TextFillColorTertiaryBrush}"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding SliderDfiValue, StringFormat=F2, Mode=OneWay}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||
FontFamily="Consolas" FontSize="16" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"/>
|
||||
<TextBlock Grid.Column="2" Text="+1.45"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom"
|
||||
FontSize="10" Foreground="{DynamicResource TextFillColorTertiaryBrush}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Read / Write buttons ──────────────────────────────────── -->
|
||||
<Grid DockPanel.Dock="Bottom" Margin="0,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:Button Grid.Column="0"
|
||||
Content="{DynamicResource Dfi.Read}"
|
||||
Command="{Binding ReadDfiCommand}"
|
||||
Appearance="Secondary"
|
||||
FontWeight="Bold" Height="32"/>
|
||||
<ui:Button Grid.Column="2"
|
||||
Content="{DynamicResource Dfi.Write}"
|
||||
Command="{Binding WriteDfiCommand}"
|
||||
Appearance="Primary"
|
||||
FontWeight="Bold" Height="32"/>
|
||||
</Grid>
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
9
Views/UserControls/DfiCalibrationCard.xaml.cs
Normal file
9
Views/UserControls/DfiCalibrationCard.xaml.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class DfiCalibrationCard : UserControl
|
||||
{
|
||||
public DfiCalibrationCard() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.DfiManageView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="150" d:DesignWidth="460" MaxHeight="150">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="LcdGreen" TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="3"/>
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="BorderBrush">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||
<GradientStop Color="DarkSlateGray" Offset="0"/>
|
||||
<GradientStop Color="LawnGreen" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||
<GradientStop Color="LawnGreen" Offset="0"/>
|
||||
<GradientStop Color="#57B000" Offset="1.5"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Margin="16,8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="75"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="144" MinWidth="60"/>
|
||||
<ColumnDefinition MinWidth="200"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- LEFT: version picker + read/write buttons -->
|
||||
<ComboBox Margin="4" VerticalAlignment="Bottom"
|
||||
SelectedIndex="{Binding VersionIndex}">
|
||||
<ComboBoxItem Content="V1"/>
|
||||
<ComboBoxItem Content="V2"/>
|
||||
<ComboBoxItem Content="V3"/>
|
||||
<ComboBoxItem Content="V4"/>
|
||||
</ComboBox>
|
||||
|
||||
<Grid Grid.Row="1" Margin="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="4"/>
|
||||
<ColumnDefinition/>
|
||||
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Content="{DynamicResource Dfi.Read}"
|
||||
Command="{Binding ReadDfiCommand}"
|
||||
FontSize="12" FontWeight="Bold" Padding="4"/>
|
||||
<Button Grid.Column="2" Content="{DynamicResource Dfi.Write}"
|
||||
Command="{Binding WriteDfiCommand}"
|
||||
FontSize="12" FontWeight="Bold" Padding="4"/>
|
||||
</Grid>
|
||||
|
||||
<!-- TOP RIGHT: DFI value LCD + auto checkbox -->
|
||||
<Grid Grid.Row="0" Grid.Column="1" Margin="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="200"/>
|
||||
<ColumnDefinition MinWidth="100"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.ColumnSpan="1" Style="{StaticResource LcdGreen}" Margin="0,0,12,0" >
|
||||
<Grid Grid.Row="1" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{DynamicResource Dfi.Label}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
Foreground="Black" FontSize="18" FontFamily="Consolas"/>
|
||||
<TextBlock Text="{Binding CurrentDfi, StringFormat=F2, Mode=OneWay}"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
FontSize="26" FontWeight="Bold" Foreground="Black"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Grid.ColumnSpan="1" BorderThickness="1" BorderBrush="Black" Margin="0,0,12,0" SnapsToDevicePixels="True"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<!-- AUTO checkbox — sits outside the column pair; placed in Column=1 outside normal layout -->
|
||||
<CheckBox IsChecked="{Binding IsAutoMode}"
|
||||
Content="{DynamicResource Dfi.Auto}"
|
||||
Grid.Row="0" Grid.Column="1"
|
||||
Height="Auto"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,10,0"
|
||||
Foreground="Black" FontSize="20"/>
|
||||
|
||||
<!-- BOTTOM RIGHT: slider with range labels + current value -->
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<Slider Value="{Binding SliderRaw}"
|
||||
Minimum="-145" Maximum="145"
|
||||
TickFrequency="5" SmallChange="5" LargeChange="5"
|
||||
IsSnapToTickEnabled="True" TickPlacement="BottomRight"
|
||||
Margin="10,0" VerticalAlignment="Center"
|
||||
Foreground="Black"/>
|
||||
<TextBlock Text="-1.45" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="10,0,0,0" Foreground="DimGray"/>
|
||||
<TextBlock Text="+1.45" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,0" Foreground="DimGray"/>
|
||||
<TextBlock Text="{Binding SliderDfiValue, StringFormat=F2, Mode=OneWay}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||
Margin="0,0,0,4" FontSize="20" Foreground="Black"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
/// <summary>Code-behind for DfiManageView — no logic; all behaviour is in the ViewModel.</summary>
|
||||
public partial class DfiManageView : UserControl
|
||||
{
|
||||
public DfiManageView() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
102
Views/UserControls/DtcCard.xaml
Normal file
102
Views/UserControls/DtcCard.xaml
Normal file
@@ -0,0 +1,102 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.DtcCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="280" d:DesignWidth="320">
|
||||
|
||||
<!-- DataContext = DtcListViewModel (via {Binding DtcList}) -->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Style="{StaticResource PumpCard}">
|
||||
<DockPanel LastChildFill="True">
|
||||
|
||||
<!-- ── Card header ───────────────────────────────────────────── -->
|
||||
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,10">
|
||||
<ui:SymbolIcon DockPanel.Dock="Left" Symbol="Warning24" FontSize="16"
|
||||
Foreground="{DynamicResource SystemFillColorCautionBrush}"
|
||||
Margin="0,0,8,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.Dtcs.Title}"
|
||||
Style="{StaticResource PumpCardHeader}" Margin="0"/>
|
||||
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right">
|
||||
<ui:Button Content="{DynamicResource Dtc.Read}"
|
||||
Command="{Binding ReadCommand}"
|
||||
Appearance="Secondary"
|
||||
Height="28" Margin="0,0,6,0"/>
|
||||
<ui:Button Content="{DynamicResource Dtc.Clear}"
|
||||
Command="{Binding ClearCommand}"
|
||||
Appearance="Secondary"
|
||||
Height="28"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
|
||||
<!-- ── Busy indicator ─────────────────────────────────────────── -->
|
||||
<ProgressBar DockPanel.Dock="Top"
|
||||
IsIndeterminate="True" Height="3" Margin="0,0,0,6"
|
||||
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVis}}"/>
|
||||
|
||||
<!-- ── Status text ─────────────────────────────────────────────── -->
|
||||
<TextBlock DockPanel.Dock="Top"
|
||||
Text="{Binding StatusText}"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<!-- ── "No faults" success pill ───────────────────────────────── -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
Background="{DynamicResource SystemFillColorSuccessBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource SystemFillColorSuccessBrush}"
|
||||
BorderThickness="1" CornerRadius="6" Padding="10,6"
|
||||
HorizontalAlignment="Left" Margin="0,0,0,4"
|
||||
Visibility="{Binding IsClear, Converter={StaticResource BoolToVis}}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ui:SymbolIcon Symbol="CheckmarkCircle24" FontSize="14"
|
||||
Foreground="{DynamicResource SystemFillColorSuccessBrush}"
|
||||
Margin="0,0,6,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Dtc.NoFaults}"
|
||||
FontSize="12" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource SystemFillColorSuccessBrush}"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- ── DTC rows ───────────────────────────────────────────────── -->
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding Codes}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="{DynamicResource SystemFillColorCautionBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource SystemFillColorCautionBrush}"
|
||||
BorderThickness="0,0,0,1" CornerRadius="4"
|
||||
Padding="8,6" Margin="0,2">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{Binding Code}"
|
||||
FontFamily="Consolas" FontWeight="Bold"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource SystemFillColorCriticalBrush}"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding Description}"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
9
Views/UserControls/DtcCard.xaml.cs
Normal file
9
Views/UserControls/DtcCard.xaml.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class DtcCard : UserControl
|
||||
{
|
||||
public DtcCard() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.DtcListView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="360" d:DesignWidth="700">
|
||||
<!--
|
||||
Pump page §3.b DTC list. DataContext = DtcListViewModel.
|
||||
Moves the fault-code surface out of the one-shot KlineErrorsDialog
|
||||
into a proper sub-section with read / clear actions and a row list.
|
||||
-->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Background="#FAFAFA" BorderBrush="#DDD" BorderThickness="1"
|
||||
CornerRadius="4" Padding="12" Margin="6">
|
||||
<DockPanel>
|
||||
|
||||
<!-- ── Header row: title + actions ─────────────────────────── -->
|
||||
<Grid DockPanel.Dock="Top" Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{DynamicResource PumpSub.Dtcs}"
|
||||
FontSize="15" FontWeight="SemiBold" Foreground="#333"
|
||||
VerticalAlignment="Center"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<Button Content="{DynamicResource Dtc.Read}"
|
||||
Command="{Binding ReadCommand}"
|
||||
MinWidth="90" Height="28" Margin="0,0,6,0"
|
||||
FontWeight="Bold"/>
|
||||
<Button Content="{DynamicResource Dtc.Clear}"
|
||||
Command="{Binding ClearCommand}"
|
||||
MinWidth="90" Height="28"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Status line ─────────────────────────────────────────── -->
|
||||
<TextBlock DockPanel.Dock="Top"
|
||||
Text="{Binding StatusText}"
|
||||
Foreground="#666" FontSize="11" Margin="0,0,0,6"/>
|
||||
|
||||
<!-- ── Busy indicator ──────────────────────────────────────── -->
|
||||
<ProgressBar DockPanel.Dock="Top"
|
||||
IsIndeterminate="True" Height="3" Margin="0,0,0,6"
|
||||
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVis}}"/>
|
||||
|
||||
<!-- ── "No faults" banner ──────────────────────────────────── -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
Background="#26C200" CornerRadius="3" Padding="10,6"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding IsClear, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock Text="{DynamicResource Dtc.NoFaults}"
|
||||
Foreground="White" FontWeight="Bold" FontSize="12"/>
|
||||
</Border>
|
||||
|
||||
<!-- ── DTC rows ────────────────────────────────────────────── -->
|
||||
<ListBox ItemsSource="{Binding Codes}"
|
||||
BorderThickness="0" Background="Transparent">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="#FDECEA" BorderBrush="#D62828"
|
||||
BorderThickness="0,0,0,1" Padding="8,6" Margin="0,2">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="110"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{Binding Code}"
|
||||
FontFamily="Consolas" FontWeight="Bold"
|
||||
FontSize="13" Foreground="#B22222"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding Description}"
|
||||
FontSize="12" Foreground="#333"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -1,16 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Pump page §3.b DTC list view. DataContext is
|
||||
/// <c>DtcListViewModel</c>.
|
||||
/// </summary>
|
||||
public partial class DtcListView : UserControl
|
||||
{
|
||||
public DtcListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
231
Views/UserControls/PumpCommandsCard.xaml
Normal file
231
Views/UserControls/PumpCommandsCard.xaml
Normal file
@@ -0,0 +1,231 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpCommandsCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="460" d:DesignWidth="260"
|
||||
IsEnabled="{Binding IsEnabled}">
|
||||
|
||||
<!-- DataContext = PumpControlViewModel (via {Binding PumpControl}) -->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
|
||||
<Style x:Key="SettingsTextBox" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="44"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsLabel" TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Margin" Value="0,2,0,0"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Style="{StaticResource PumpCard}">
|
||||
<DockPanel LastChildFill="True">
|
||||
|
||||
<!-- ── Card header ───────────────────────────────────────────── -->
|
||||
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,12">
|
||||
<ui:SymbolIcon DockPanel.Dock="Left" Symbol="ArrowTrendingLines24" FontSize="16"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
|
||||
Margin="0,0,8,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.Commands.Title}"
|
||||
Style="{StaticResource PumpCardHeader}" Margin="0"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- ── Slider columns ────────────────────────────────────────── -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- PreIn: collapses when not applicable -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- ── FBKW ────────────────────────────────────────────── -->
|
||||
<StackPanel Grid.Column="0" HorizontalAlignment="Center">
|
||||
<!-- Settings toggle -->
|
||||
<ToggleButton x:Name="FbkwToggle"
|
||||
Width="28" Height="22"
|
||||
HorizontalAlignment="Center"
|
||||
Background="Transparent" BorderBrush="Transparent"
|
||||
Content="..." FontWeight="Bold" FontSize="13"
|
||||
ToolTip="{DynamicResource PumpCtrl.MinStepMax}"/>
|
||||
|
||||
<!-- Max label -->
|
||||
<TextBlock Text="{Binding FbkwMax, StringFormat=F1}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,4,0,2"/>
|
||||
|
||||
<!-- Vertical slider -->
|
||||
<Slider Orientation="Vertical"
|
||||
Minimum="{Binding FbkwMin}" Maximum="{Binding FbkwMax}"
|
||||
Value="{Binding FbkwValue}"
|
||||
TickFrequency="{Binding FbkwStep}"
|
||||
TickPlacement="TopLeft"
|
||||
IsSnapToTickEnabled="True"
|
||||
AutoToolTipPrecision="2"
|
||||
Height="240" Width="32"
|
||||
HorizontalAlignment="Center"
|
||||
Focusable="False"/>
|
||||
|
||||
<!-- Min label -->
|
||||
<TextBlock Text="{Binding FbkwMin, StringFormat=F1}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,2,0,6"/>
|
||||
|
||||
<!-- Editable value box -->
|
||||
<TextBox Text="{Binding FbkwValue, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}"
|
||||
Style="{StaticResource PumpCommandValue}"/>
|
||||
|
||||
<!-- Parameter name -->
|
||||
<TextBlock Text="{DynamicResource Pump.Commands.Fbkw}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,6,0,0"/>
|
||||
|
||||
<!-- Settings popup -->
|
||||
<Popup IsOpen="{Binding IsChecked, ElementName=FbkwToggle}"
|
||||
StaysOpen="False" Placement="Bottom" AllowsTransparency="True">
|
||||
<Border Background="#BB000000" Padding="8,6" CornerRadius="3">
|
||||
<UniformGrid Columns="3" Width="180">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding FbkwMin, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Min}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding FbkwStep, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Step}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding FbkwMax, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Max}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
</Border>
|
||||
</Popup>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── ME ──────────────────────────────────────────────── -->
|
||||
<StackPanel Grid.Column="1" HorizontalAlignment="Center">
|
||||
<ToggleButton x:Name="MeToggle"
|
||||
Width="28" Height="22"
|
||||
HorizontalAlignment="Center"
|
||||
Background="Transparent" BorderBrush="Transparent"
|
||||
Content="..." FontWeight="Bold" FontSize="13"
|
||||
ToolTip="{DynamicResource PumpCtrl.MinStepMax}"/>
|
||||
|
||||
<TextBlock Text="{Binding MeMax, StringFormat=F1}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,4,0,2"/>
|
||||
|
||||
<Slider Orientation="Vertical"
|
||||
Minimum="{Binding MeMin}" Maximum="{Binding MeMax}"
|
||||
Value="{Binding MeValue}"
|
||||
TickFrequency="{Binding MeStep}"
|
||||
TickPlacement="TopLeft"
|
||||
IsSnapToTickEnabled="False"
|
||||
AutoToolTipPrecision="2"
|
||||
Height="240" Width="32"
|
||||
HorizontalAlignment="Center"
|
||||
Focusable="False"/>
|
||||
|
||||
<TextBlock Text="{Binding MeMin, StringFormat=F1}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,2,0,6"/>
|
||||
|
||||
<TextBox Text="{Binding MeValue, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}"
|
||||
Style="{StaticResource PumpCommandValue}"/>
|
||||
|
||||
<TextBlock Text="{DynamicResource Pump.Commands.Me}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,6,0,0"/>
|
||||
|
||||
<Popup IsOpen="{Binding IsChecked, ElementName=MeToggle}"
|
||||
StaysOpen="False" Placement="Bottom" AllowsTransparency="True">
|
||||
<Border Background="#BB000000" Padding="8,6" CornerRadius="3">
|
||||
<UniformGrid Columns="3" Width="180">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding MeMin, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Min}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding MeStep, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Step}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding MeMax, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Max}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
</Border>
|
||||
</Popup>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── PreIn (conditional) ─────────────────────────────── -->
|
||||
<StackPanel Grid.Column="2" HorizontalAlignment="Center"
|
||||
Visibility="{Binding IsPreInVisible, Converter={StaticResource BoolToVis}}">
|
||||
<ToggleButton x:Name="PreInToggle"
|
||||
Width="28" Height="22"
|
||||
HorizontalAlignment="Center"
|
||||
Background="Transparent" BorderBrush="Transparent"
|
||||
Content="..." FontWeight="Bold" FontSize="13"
|
||||
ToolTip="{DynamicResource PumpCtrl.MinStepMax}"/>
|
||||
|
||||
<TextBlock Text="{Binding PreInMax, StringFormat=F1}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,4,0,2"/>
|
||||
|
||||
<Slider Orientation="Vertical"
|
||||
Minimum="{Binding PreInMin}" Maximum="{Binding PreInMax}"
|
||||
Value="{Binding PreInValue}"
|
||||
TickFrequency="{Binding PreInStep}"
|
||||
TickPlacement="TopLeft"
|
||||
IsSnapToTickEnabled="True"
|
||||
AutoToolTipPrecision="2"
|
||||
Height="240" Width="32"
|
||||
HorizontalAlignment="Center"
|
||||
Focusable="False"/>
|
||||
|
||||
<TextBlock Text="{Binding PreInMin, StringFormat=F1}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,2,0,6"/>
|
||||
|
||||
<TextBox Text="{Binding PreInValue, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}"
|
||||
Style="{StaticResource PumpCommandValue}"/>
|
||||
|
||||
<TextBlock Text="{DynamicResource Pump.Commands.PreIn}"
|
||||
Style="{StaticResource PumpCommandLabel}"
|
||||
Margin="0,6,0,0"/>
|
||||
|
||||
<Popup IsOpen="{Binding IsChecked, ElementName=PreInToggle}"
|
||||
StaysOpen="False" Placement="Bottom" AllowsTransparency="True">
|
||||
<Border Background="#BB000000" Padding="8,6" CornerRadius="3">
|
||||
<UniformGrid Columns="3" Width="180">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding PreInMin, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Min}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding PreInStep, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Step}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding PreInMax, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Max}" Style="{StaticResource SettingsLabel}"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
</Border>
|
||||
</Popup>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
9
Views/UserControls/PumpCommandsCard.xaml.cs
Normal file
9
Views/UserControls/PumpCommandsCard.xaml.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class PumpCommandsCard : UserControl
|
||||
{
|
||||
public PumpCommandsCard() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpControlView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="260" d:DesignWidth="440"
|
||||
IsEnabled="{Binding IsEnabled}">
|
||||
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
|
||||
<!-- Shared style for the settings popup min/max/step text boxes -->
|
||||
<Style x:Key="SettingsTextBox" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="40"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
</Style>
|
||||
|
||||
<!-- Label inside settings popup -->
|
||||
<Style x:Key="SettingsLabel" TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Margin" Value="0,2,0,0"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel>
|
||||
|
||||
<!-- ═══ FBKW — Advance Control ═══════════════════════════════════════ -->
|
||||
<Grid Margin="6,6,6,2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Fbkw}" HorizontalAlignment="Center"
|
||||
FontSize="13" Foreground="Black" Margin="0,0,0,2"/>
|
||||
|
||||
<DockPanel Grid.Row="1" Margin="4,0,4,2">
|
||||
<!-- Settings button -->
|
||||
<ToggleButton x:Name="FbkwSettingsToggle" DockPanel.Dock="Left"
|
||||
Width="28" Height="28" Margin="0,0,4,0"
|
||||
Background="Transparent" BorderBrush="Transparent"
|
||||
Content="..." FontWeight="Bold" FontSize="14"
|
||||
ToolTip="{DynamicResource PumpCtrl.MinStepMax}"/>
|
||||
<!-- Numeric text box -->
|
||||
<TextBox DockPanel.Dock="Right" Width="50" Height="28" Margin="4,0,0,0"
|
||||
TextAlignment="Center" VerticalContentAlignment="Center"
|
||||
FontWeight="Bold" FontSize="13"
|
||||
Text="{Binding FbkwValue, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}"/>
|
||||
<!-- Slider -->
|
||||
<Slider Minimum="{Binding FbkwMin}" Maximum="{Binding FbkwMax}"
|
||||
Value="{Binding FbkwValue}" TickFrequency="{Binding FbkwStep}"
|
||||
TickPlacement="BottomRight" AutoToolTipPrecision="2"
|
||||
IsSnapToTickEnabled="True" VerticalAlignment="Center"
|
||||
Focusable="False" Foreground="Black"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Settings popup -->
|
||||
<Popup IsOpen="{Binding IsChecked, ElementName=FbkwSettingsToggle}"
|
||||
StaysOpen="False" Placement="Bottom" AllowsTransparency="True"
|
||||
HorizontalOffset="30">
|
||||
<Border Background="#BB000000" Padding="8,6" CornerRadius="3">
|
||||
<UniformGrid Columns="3" Width="180">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding FbkwMin, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Min}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding FbkwStep, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Step}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding FbkwMax, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Max}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
</Border>
|
||||
</Popup>
|
||||
</Grid>
|
||||
|
||||
<!-- ═══ ME — Quantity Control ════════════════════════════════════════ -->
|
||||
<Grid Margin="6,4,6,2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Me}" HorizontalAlignment="Center"
|
||||
FontSize="13" Foreground="Black" Margin="0,0,0,2"/>
|
||||
|
||||
<DockPanel Grid.Row="1" Margin="4,0,4,2">
|
||||
<ToggleButton x:Name="MeSettingsToggle" DockPanel.Dock="Left"
|
||||
Width="28" Height="28" Margin="0,0,4,0"
|
||||
Background="Transparent" BorderBrush="Transparent"
|
||||
Content="..." FontWeight="Bold" FontSize="14"
|
||||
ToolTip="{DynamicResource PumpCtrl.MinStepMax}"/>
|
||||
<TextBox DockPanel.Dock="Right" Width="50" Height="28" Margin="4,0,0,0"
|
||||
TextAlignment="Center" VerticalContentAlignment="Center"
|
||||
FontWeight="Bold" FontSize="13"
|
||||
Text="{Binding MeValue, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}"/>
|
||||
<Slider Minimum="{Binding MeMin}" Maximum="{Binding MeMax}"
|
||||
Value="{Binding MeValue}" TickFrequency="{Binding MeStep}"
|
||||
TickPlacement="BottomRight" AutoToolTipPrecision="2"
|
||||
IsSnapToTickEnabled="False" VerticalAlignment="Center"
|
||||
Focusable="False" Foreground="Black"/>
|
||||
</DockPanel>
|
||||
|
||||
<Popup IsOpen="{Binding IsChecked, ElementName=MeSettingsToggle}"
|
||||
StaysOpen="False" Placement="Bottom" AllowsTransparency="True"
|
||||
HorizontalOffset="30">
|
||||
<Border Background="#BB000000" Padding="8,6" CornerRadius="3">
|
||||
<UniformGrid Columns="3" Width="180">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding MeMin, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Min}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding MeStep, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Step}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding MeMax, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Max}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
</Border>
|
||||
</Popup>
|
||||
</Grid>
|
||||
|
||||
<!-- ═══ PreIn — Pre-injection Quantity ═══════════════════════════════ -->
|
||||
<Grid Margin="6,4,6,2"
|
||||
Visibility="{Binding IsPreInVisible, Converter={StaticResource BoolToVis}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.PreInj}" HorizontalAlignment="Center"
|
||||
FontSize="13" Foreground="Black" Margin="0,0,0,2"/>
|
||||
|
||||
<DockPanel Grid.Row="1" Margin="4,0,4,2">
|
||||
<ToggleButton x:Name="PreInSettingsToggle" DockPanel.Dock="Left"
|
||||
Width="28" Height="28" Margin="0,0,4,0"
|
||||
Background="Transparent" BorderBrush="Transparent"
|
||||
Content="..." FontWeight="Bold" FontSize="14"
|
||||
ToolTip="{DynamicResource PumpCtrl.MinStepMax}"/>
|
||||
<TextBox DockPanel.Dock="Right" Width="50" Height="28" Margin="4,0,0,0"
|
||||
TextAlignment="Center" VerticalContentAlignment="Center"
|
||||
FontWeight="Bold" FontSize="13"
|
||||
Text="{Binding PreInValue, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}"/>
|
||||
<Slider Minimum="{Binding PreInMin}" Maximum="{Binding PreInMax}"
|
||||
Value="{Binding PreInValue}" TickFrequency="{Binding PreInStep}"
|
||||
TickPlacement="BottomRight" AutoToolTipPrecision="2"
|
||||
IsSnapToTickEnabled="True" VerticalAlignment="Center"
|
||||
Focusable="False" Foreground="Black"/>
|
||||
</DockPanel>
|
||||
|
||||
<Popup IsOpen="{Binding IsChecked, ElementName=PreInSettingsToggle}"
|
||||
StaysOpen="False" Placement="Bottom" AllowsTransparency="True"
|
||||
HorizontalOffset="30">
|
||||
<Border Background="#BB000000" Padding="8,6" CornerRadius="3">
|
||||
<UniformGrid Columns="3" Width="180">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding PreInMin, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Min}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding PreInStep, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Step}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBox Text="{Binding PreInMax, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource SettingsTextBox}"/>
|
||||
<TextBlock Text="{DynamicResource PumpCtrl.Max}" Style="{StaticResource SettingsLabel}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
</Border>
|
||||
</Popup>
|
||||
</Grid>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Manual pump control sliders (FBKW, ME, PreIn) with configurable min/max/step popups.
|
||||
/// </summary>
|
||||
public partial class PumpControlView : UserControl
|
||||
{
|
||||
public PumpControlView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +1,82 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpIdentificationPanelView"
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpIdentificationCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="360" d:DesignWidth="700">
|
||||
<!--
|
||||
Pump-page variant of PumpIdentificationView (spec §3.a Identification).
|
||||
Reuses PumpIdentificationViewModel. Presents the ECU info panel
|
||||
in a larger, two-column format suitable for the Pump page.
|
||||
-->
|
||||
d:DesignHeight="360" d:DesignWidth="320">
|
||||
|
||||
<!-- DataContext = PumpIdentificationViewModel (via {Binding Identification}) -->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
|
||||
<Style x:Key="IdLabel" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#555"/>
|
||||
<Setter Property="Width" Value="110"/>
|
||||
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}"/>
|
||||
<Setter Property="Width" Value="88"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IdValue" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="FontFamily" Value="Consolas"/>
|
||||
<Setter Property="FontFamily" Value="Consolas"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Background="#FAFAFA" BorderBrush="#DDD" BorderThickness="1"
|
||||
CornerRadius="4" Padding="12" Margin="6">
|
||||
<StackPanel>
|
||||
<Border Style="{StaticResource PumpCard}">
|
||||
<DockPanel LastChildFill="True">
|
||||
|
||||
<!-- ── Section title ────────────────────────────────────────── -->
|
||||
<TextBlock Text="{DynamicResource PumpSub.Identification}"
|
||||
FontSize="15" FontWeight="SemiBold" Foreground="#333"
|
||||
Margin="0,0,0,8"/>
|
||||
<!-- ── Card header ───────────────────────────────────────────── -->
|
||||
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,12">
|
||||
<ui:SymbolIcon DockPanel.Dock="Left" Symbol="Server24" FontSize="16"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
|
||||
Margin="0,0,8,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.Identification.Title}"
|
||||
Style="{StaticResource PumpCardHeader}"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- ── Pump selector row ────────────────────────────────────── -->
|
||||
<Grid Margin="0,0,0,10">
|
||||
<!-- ── Action row: Read + Disconnect + progress ──────────────── -->
|
||||
<Grid DockPanel.Dock="Top" Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="110"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{DynamicResource PumpId.Label}"
|
||||
VerticalAlignment="Center" FontSize="13"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
ItemsSource="{Binding PumpIds}"
|
||||
SelectedItem="{Binding SelectedPumpId}"
|
||||
FontSize="18" Margin="0,0,12,0"
|
||||
VerticalContentAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="{Binding CurrentPump.Model}"
|
||||
FontSize="13" Foreground="#888"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Action row: Read + Disconnect + progress ─────────────── -->
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0"
|
||||
Content="{DynamicResource PumpId.ReadKLine}"
|
||||
Command="{Binding ReadKlineCommand}"
|
||||
MinWidth="130" Height="34" FontWeight="Bold"
|
||||
Margin="0,0,8,0"/>
|
||||
<Button Grid.Column="1"
|
||||
Content="{DynamicResource PumpId.Disconnect}"
|
||||
Command="{Binding DisconnectKLineCommand}"
|
||||
MinWidth="110" Height="34"
|
||||
Margin="0,0,12,0"/>
|
||||
<StackPanel Grid.Column="2"
|
||||
Orientation="Vertical"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding IsReading, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock Text="{Binding ProgressMessage}"
|
||||
FontSize="11" Foreground="#666"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
<ProgressBar Value="{Binding ProgressPercent, Mode=OneWay}"
|
||||
Minimum="0" Maximum="100" Height="8" Margin="0,2,0,0"/>
|
||||
</StackPanel>
|
||||
<ui:Button Grid.Column="0"
|
||||
Content="{DynamicResource PumpId.ReadKLine}"
|
||||
Command="{Binding ReadKlineCommand}"
|
||||
Appearance="Primary"
|
||||
FontWeight="Bold" Height="32"/>
|
||||
<ui:Button Grid.Column="2"
|
||||
Content="{DynamicResource PumpId.Disconnect}"
|
||||
Command="{Binding DisconnectKLineCommand}"
|
||||
Appearance="Secondary"
|
||||
Height="32"/>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Two-column ECU info grid ─────────────────────────────── -->
|
||||
<!-- ── Inline progress (visible while reading) ───────────────── -->
|
||||
<StackPanel DockPanel.Dock="Top"
|
||||
Margin="0,0,0,8"
|
||||
Visibility="{Binding IsReading, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock Text="{Binding ProgressMessage}"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Margin="0,0,0,3"/>
|
||||
<ProgressBar Value="{Binding ProgressPercent, Mode=OneWay}"
|
||||
Minimum="0" Maximum="100" Height="4"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── ECU info: two columns ─────────────────────────────────── -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
@@ -139,14 +124,18 @@
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,2">
|
||||
<TextBlock Text="{DynamicResource PumpId.Errors}" Style="{StaticResource IdLabel}"/>
|
||||
<TextBlock Text="{Binding KlineErrors}" Style="{StaticResource IdValue}" Foreground="DarkRed"/>
|
||||
<TextBlock Text="{Binding KlineErrors}" Style="{StaticResource IdValue}"
|
||||
Foreground="{DynamicResource SystemFillColorCriticalBrush}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Connection error footer (auto-collapses) ─────────────── -->
|
||||
<Border Background="#FDECEA" BorderBrush="#D62828" BorderThickness="1"
|
||||
CornerRadius="3" Padding="8,4" Margin="0,10,0,0">
|
||||
<!-- ── Connection error footer ──────────────────────────────── -->
|
||||
<Border DockPanel.Dock="Bottom"
|
||||
Background="{DynamicResource SystemFillColorCriticalBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource SystemFillColorCriticalBrush}"
|
||||
BorderThickness="1" CornerRadius="4"
|
||||
Padding="8,4" Margin="0,10,0,0">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Style.Triggers>
|
||||
@@ -157,9 +146,11 @@
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{Binding KlineConnectError}"
|
||||
FontSize="12" FontFamily="Consolas" Foreground="#B22222"
|
||||
FontSize="11" FontFamily="Consolas"
|
||||
Foreground="{DynamicResource SystemFillColorCriticalBrush}"
|
||||
TextWrapping="Wrap"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
9
Views/UserControls/PumpIdentificationCard.xaml.cs
Normal file
9
Views/UserControls/PumpIdentificationCard.xaml.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class PumpIdentificationCard : UserControl
|
||||
{
|
||||
public PumpIdentificationCard() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Larger page-scoped variant of <see cref="PumpIdentificationView"/> used by the
|
||||
/// Pump page §3.a Identification sub-section. DataContext is
|
||||
/// <c>PumpIdentificationViewModel</c>.
|
||||
/// </summary>
|
||||
public partial class PumpIdentificationPanelView : UserControl
|
||||
{
|
||||
public PumpIdentificationPanelView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
175
Views/UserControls/PumpLiveDataCard.xaml
Normal file
175
Views/UserControls/PumpLiveDataCard.xaml
Normal file
@@ -0,0 +1,175 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpLiveDataCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
|
||||
xmlns:uc="clr-namespace:HC_APTBS.Views.UserControls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="700" d:DesignWidth="500">
|
||||
|
||||
<!--
|
||||
DataContext = PumpPageViewModel.
|
||||
Live values accessed via Root.PumpRpm / Root.PumpTemp / Root.PumpMe / Root.PumpFbkw / Root.PumpTein.
|
||||
Status words accessed via StatusDisplay1 and StatusDisplay2 (both StatusDisplayViewModel).
|
||||
RPM chart via RpmChart (SingleFlowChartViewModel).
|
||||
-->
|
||||
<Border Style="{StaticResource PumpCard}">
|
||||
<DockPanel LastChildFill="True">
|
||||
|
||||
<!-- ── Card header ───────────────────────────────────────────── -->
|
||||
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,12">
|
||||
<ui:SymbolIcon DockPanel.Dock="Left" Symbol="PulseSquare24" FontSize="16"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
|
||||
Margin="0,0,8,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.LiveData.Title}"
|
||||
Style="{StaticResource PumpCardHeader}" Margin="0"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- ── Status displays (docked bottom so chart gets the middle) ── -->
|
||||
<StackPanel DockPanel.Dock="Bottom" Margin="0,8,0,0">
|
||||
<uc:StatusDisplayView DataContext="{Binding StatusDisplay1}" Margin="0,0,0,8"/>
|
||||
<uc:StatusDisplayView DataContext="{Binding StatusDisplay2}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── RPM chart (docked bottom of the upper area) ──────────── -->
|
||||
<Border DockPanel.Dock="Bottom"
|
||||
Background="{DynamicResource ControlFillColorSecondaryBrush}"
|
||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||
BorderThickness="1" CornerRadius="6"
|
||||
Padding="4,4" Margin="0,8,0,0">
|
||||
<DockPanel LastChildFill="True">
|
||||
<TextBlock DockPanel.Dock="Top"
|
||||
Text="{DynamicResource Pump.LiveData.RpmChart}"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="4,0,0,2"/>
|
||||
<lvc:CartesianChart Height="110"
|
||||
Series="{Binding RpmChart.Series}"
|
||||
XAxes="{Binding RpmChart.XAxes}"
|
||||
YAxes="{Binding RpmChart.YAxes}"
|
||||
TooltipPosition="Hidden"
|
||||
AnimationsSpeed="00:00:00"/>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<!-- ── KPI tiles (top portion, fills remaining space) ────────── -->
|
||||
<UniformGrid Rows="1" Columns="5">
|
||||
|
||||
<!-- RPM -->
|
||||
<Border Style="{StaticResource KpiTile}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ui:SymbolIcon Symbol="Gauge24" FontSize="14"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,4,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.LiveData.RPM}"
|
||||
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<TextBlock Text="{Binding Root.PumpRpm, StringFormat=F0}"
|
||||
Style="{StaticResource KpiValueText}" FontSize="32"/>
|
||||
<TextBlock Text="{DynamicResource Pump.UnitRpm}"
|
||||
Style="{StaticResource KpiUnitText}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- T-hyb -->
|
||||
<Border Style="{StaticResource KpiTile}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ui:SymbolIcon Symbol="Temperature24" FontSize="14"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,4,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.LiveData.THyb}"
|
||||
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<TextBlock Text="{Binding Root.PumpTemp, StringFormat=F1}"
|
||||
Style="{StaticResource KpiValueText}" FontSize="32"/>
|
||||
<TextBlock Text="{DynamicResource Pump.UnitCelsius}"
|
||||
Style="{StaticResource KpiUnitText}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- T-ein -->
|
||||
<Border Style="{StaticResource KpiTile}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ui:SymbolIcon Symbol="Timer24" FontSize="14"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,4,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.LiveData.TEin}"
|
||||
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<TextBlock Text="{Binding Root.PumpTein, StringFormat=F0}"
|
||||
Style="{StaticResource KpiValueText}" FontSize="32"/>
|
||||
<TextBlock Text="{DynamicResource Pump.UnitUs}"
|
||||
Style="{StaticResource KpiUnitText}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ME -->
|
||||
<Border Style="{StaticResource KpiTile}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ui:SymbolIcon Symbol="ArrowTrendingLines24" FontSize="14"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,4,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.LiveData.Me}"
|
||||
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<TextBlock Text="{Binding Root.PumpMe, StringFormat=F2}"
|
||||
Style="{StaticResource KpiValueText}" FontSize="32"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- FBKW -->
|
||||
<Border Style="{StaticResource KpiTile}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ui:SymbolIcon Symbol="ArrowTrendingLines24" FontSize="14"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,4,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource Pump.LiveData.Fbkw}"
|
||||
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<TextBlock Text="{Binding Root.PumpFbkw, StringFormat=F2}"
|
||||
Style="{StaticResource KpiValueText}" FontSize="32"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</UniformGrid>
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
9
Views/UserControls/PumpLiveDataCard.xaml.cs
Normal file
9
Views/UserControls/PumpLiveDataCard.xaml.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class PumpLiveDataCard : UserControl
|
||||
{
|
||||
public PumpLiveDataCard() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpLiveDataView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="clr-namespace:HC_APTBS.Views.UserControls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="380" d:DesignWidth="700">
|
||||
<!--
|
||||
Pump page §3.c Live Data. DataContext = PumpPageViewModel so the view
|
||||
can reach the MainViewModel-owned live readings via {Binding Root.X}
|
||||
and the two StatusDisplay VMs.
|
||||
-->
|
||||
<Border Background="#FAFAFA" BorderBrush="#DDD" BorderThickness="1"
|
||||
CornerRadius="4" Padding="12" Margin="6">
|
||||
<StackPanel>
|
||||
|
||||
<!-- ── Section title ─────────────────────────────────────────── -->
|
||||
<TextBlock Text="{DynamicResource PumpSub.LiveData}"
|
||||
FontSize="15" FontWeight="SemiBold" Foreground="#333"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<!-- ── LCD-style readings block ──────────────────────────────── -->
|
||||
<Border Style="{StaticResource LcdBlue}" Padding="10,6">
|
||||
<Grid Height="110">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="60"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Left column: T-hyb / RPM / T-ein -->
|
||||
<TextBlock Text="{DynamicResource Pump.THyb}"
|
||||
VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="13"/>
|
||||
<TextBlock Text="{DynamicResource Pump.Rpm}"
|
||||
Grid.Row="1" VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="13"/>
|
||||
<TextBlock Text="{DynamicResource Pump.TEin}"
|
||||
Grid.Row="2" VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="13"/>
|
||||
|
||||
<TextBlock Text="{Binding Root.PumpTemp, StringFormat=F2}"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Foreground="#EBEBFF" FontSize="22" FontWeight="Bold" FontFamily="Consolas"/>
|
||||
<TextBlock Text="{Binding Root.PumpRpm, StringFormat=F0}"
|
||||
Grid.Column="1" Grid.Row="1"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Foreground="#EBEBFF" FontSize="22" FontWeight="Bold" FontFamily="Consolas"/>
|
||||
<TextBlock Text="{Binding Root.PumpTein, StringFormat=F0}"
|
||||
Grid.Column="1" Grid.Row="2"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Foreground="#EBEBFF" FontSize="22" FontWeight="Bold" FontFamily="Consolas"/>
|
||||
|
||||
<TextBlock Text="°C" Grid.Column="2"
|
||||
VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="12" Margin="4,0"/>
|
||||
<TextBlock Text="{DynamicResource Pump.UnitRpm}"
|
||||
Grid.Column="2" Grid.Row="1"
|
||||
VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="12" Margin="4,0"/>
|
||||
<TextBlock Text="µs" Grid.Column="2" Grid.Row="2"
|
||||
VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="12" Margin="4,0"/>
|
||||
|
||||
<!-- Right column: ME / FBKW -->
|
||||
<TextBlock Text="{DynamicResource Bench.PumpMe}"
|
||||
Grid.Column="4" VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="13"/>
|
||||
<TextBlock Text="{DynamicResource Bench.PumpFbkw}"
|
||||
Grid.Column="4" Grid.Row="1"
|
||||
VerticalAlignment="Center" Foreground="#EBEBFF" FontSize="13"/>
|
||||
|
||||
<TextBlock Text="{Binding Root.PumpMe, StringFormat=F2}"
|
||||
Grid.Column="5"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Foreground="#EBEBFF" FontSize="22" FontWeight="Bold" FontFamily="Consolas"/>
|
||||
<TextBlock Text="{Binding Root.PumpFbkw, StringFormat=F2}"
|
||||
Grid.Column="5" Grid.Row="1"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Foreground="#EBEBFF" FontSize="22" FontWeight="Bold" FontFamily="Consolas"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ── Status displays (Status word + Empf3) ─────────────────── -->
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<uc:StatusDisplayView DataContext="{Binding StatusDisplay1}"/>
|
||||
<uc:StatusDisplayView DataContext="{Binding StatusDisplay2}" Margin="0,4,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── Engineering expander (raw values) ─────────────────────── -->
|
||||
<Expander Header="{DynamicResource PumpLive.Engineering}"
|
||||
IsExpanded="False" Margin="0,10,0,0" FontSize="12">
|
||||
<Border Background="#1E1E1E" Padding="10,6" CornerRadius="2">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Foreground="#9CDCFE" FontFamily="Consolas" FontSize="11">
|
||||
<Run Text="PumpRpm = "/><Run Text="{Binding Root.PumpRpm, StringFormat=F2, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
<TextBlock Foreground="#9CDCFE" FontFamily="Consolas" FontSize="11">
|
||||
<Run Text="PumpTemp = "/><Run Text="{Binding Root.PumpTemp, StringFormat=F2, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
<TextBlock Foreground="#9CDCFE" FontFamily="Consolas" FontSize="11">
|
||||
<Run Text="PumpMe = "/><Run Text="{Binding Root.PumpMe, StringFormat=F3, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Foreground="#9CDCFE" FontFamily="Consolas" FontSize="11">
|
||||
<Run Text="PumpFbkw = "/><Run Text="{Binding Root.PumpFbkw, StringFormat=F3, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
<TextBlock Foreground="#9CDCFE" FontFamily="Consolas" FontSize="11">
|
||||
<Run Text="PumpTein = "/><Run Text="{Binding Root.PumpTein, StringFormat=F0, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
<TextBlock Foreground="#9CDCFE" FontFamily="Consolas" FontSize="11">
|
||||
<Run Text="KLineState = "/><Run Text="{Binding Root.KLineState, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Expander>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Pump page §3.c Live Data view: pump CAN readings, status-word displays,
|
||||
/// and a collapsible engineering panel. DataContext is
|
||||
/// <c>PumpPageViewModel</c> (reaches MainViewModel via <c>Root</c>).
|
||||
/// </summary>
|
||||
public partial class PumpLiveDataView : UserControl
|
||||
{
|
||||
public PumpLiveDataView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
162
Views/UserControls/PumpTopStripView.xaml
Normal file
162
Views/UserControls/PumpTopStripView.xaml
Normal file
@@ -0,0 +1,162 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.PumpTopStripView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:models="clr-namespace:HC_APTBS.Models"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="52" d:DesignWidth="1100">
|
||||
|
||||
<!-- DataContext = PumpPageViewModel. Binds via Root.* and Identification.* -->
|
||||
<Border Background="{DynamicResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1" CornerRadius="8"
|
||||
Padding="14,10" Margin="0,0,0,8">
|
||||
<DockPanel LastChildFill="False">
|
||||
|
||||
<!-- ── Right side: CAN chip + K-Line chip ────────────────────── -->
|
||||
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
|
||||
<!-- CAN chip -->
|
||||
<Border Style="{StaticResource ConnChip}">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<ui:SymbolIcon Symbol="PlugConnected24" FontSize="15"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,6,0"/>
|
||||
<TextBlock Text="{DynamicResource Pump.TopStrip.Can}" FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,10,0"/>
|
||||
<Ellipse>
|
||||
<Ellipse.Style>
|
||||
<Style TargetType="Ellipse" BasedOn="{StaticResource StatusDot}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.IsCanConnected}" Value="True">
|
||||
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Ellipse.Style>
|
||||
</Ellipse>
|
||||
<TextBlock FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOffline}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.IsCanConnected}" Value="True">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOnline}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- K-Line chip — 3-state: Connected / Closed / Failed -->
|
||||
<Border Margin="0,0,0,0">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource ConnChip}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.KLineState}"
|
||||
Value="{x:Static models:KLineConnectionState.Failed}">
|
||||
<Setter Property="Background" Value="{DynamicResource SystemFillColorCautionBackgroundBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource SystemFillColorCautionBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<ui:SymbolIcon Symbol="UsbPlug24" FontSize="15"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,6,0"/>
|
||||
<TextBlock Text="{DynamicResource Pump.TopStrip.KLine}" FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,10,0"/>
|
||||
<Ellipse>
|
||||
<Ellipse.Style>
|
||||
<Style TargetType="Ellipse" BasedOn="{StaticResource StatusDot}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.KLineState}"
|
||||
Value="{x:Static models:KLineConnectionState.Connected}">
|
||||
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Root.KLineState}"
|
||||
Value="{x:Static models:KLineConnectionState.Failed}">
|
||||
<Setter Property="Fill" Value="{DynamicResource SystemFillColorCautionBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Ellipse.Style>
|
||||
</Ellipse>
|
||||
<TextBlock FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.StateClosed}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.KLineState}"
|
||||
Value="{x:Static models:KLineConnectionState.Connected}">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOpen}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Root.KLineState}"
|
||||
Value="{x:Static models:KLineConnectionState.Failed}">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.StateFailed}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorCautionBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── Left side: Pump selector + Brand/Model label ─────────── -->
|
||||
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<!-- Pump ID label -->
|
||||
<TextBlock Text="{DynamicResource PumpId.Label}"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
|
||||
<!-- Pump selector ComboBox -->
|
||||
<ComboBox ItemsSource="{Binding Identification.PumpIds}"
|
||||
SelectedItem="{Binding Identification.SelectedPumpId}"
|
||||
MinWidth="200" FontSize="13" Height="32"
|
||||
VerticalContentAlignment="Center"/>
|
||||
|
||||
<!-- Model / Brand badge -->
|
||||
<Border Background="{DynamicResource ControlFillColorSecondaryBrush}"
|
||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||
BorderThickness="1" CornerRadius="10" Padding="10,4" Margin="10,0,0,0">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Pump.TopStrip.Brand}"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,4,0"/>
|
||||
<TextBlock FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{Binding Identification.CurrentPump.Model}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Identification.CurrentPump}" Value="{x:Null}">
|
||||
<Setter Property="Text" Value="{DynamicResource Pump.TopStrip.NoPump}"/>
|
||||
<Setter Property="FontStyle" Value="Italic"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
9
Views/UserControls/PumpTopStripView.xaml.cs
Normal file
9
Views/UserControls/PumpTopStripView.xaml.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class PumpTopStripView : UserControl
|
||||
{
|
||||
public PumpTopStripView() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:conv="clr-namespace:HC_APTBS.Converters"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="70" d:DesignWidth="375">
|
||||
d:DesignHeight="90" d:DesignWidth="340">
|
||||
|
||||
<UserControl.Resources>
|
||||
<conv:HexColorToBrushConverter x:Key="HexToBrush"/>
|
||||
@@ -13,45 +13,70 @@
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock Text="{Binding Title}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
FontSize="14" FontWeight="SemiBold" Foreground="Black"/>
|
||||
<!-- Header: title (left) + "Active: n/16" chip (right) -->
|
||||
<DockPanel Margin="0,0,0,6">
|
||||
<Border DockPanel.Dock="Right"
|
||||
Background="{DynamicResource ControlFillColorSecondaryBrush}"
|
||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||
BorderThickness="1" CornerRadius="10" Padding="8,2">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Pump.Status.Active}"
|
||||
FontSize="11" FontFamily="{DynamicResource ContentControlThemeFontFamily}"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,0,3,0"/>
|
||||
<TextBlock Text=": " FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
|
||||
<TextBlock Text="{Binding ActiveCount}"
|
||||
FontSize="11" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||
<TextBlock Text="/16" FontSize="11"
|
||||
Foreground="{DynamicResource TextFillColorTertiaryBrush}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<TextBlock Text="{Binding Title}"
|
||||
FontSize="12" FontWeight="SemiBold"
|
||||
FontFamily="{DynamicResource ContentControlThemeFontFamily}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"/>
|
||||
</DockPanel>
|
||||
|
||||
<!-- 16-bit indicator row -->
|
||||
<ItemsControl Grid.Row="1"
|
||||
ItemsSource="{Binding Bits}"
|
||||
Margin="10,0,10,6">
|
||||
<!-- 2×8 grid of rounded bit tiles -->
|
||||
<ItemsControl Grid.Row="1" ItemsSource="{Binding Bits}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<UniformGrid Rows="1"/>
|
||||
<UniformGrid Rows="2" Columns="8"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<!-- Each bit: coloured dot + bit-number label -->
|
||||
<Grid Margin="1,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="3*"/>
|
||||
<RowDefinition Height="2*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Rectangle Fill="{Binding Color, Converter={StaticResource HexToBrush}}"
|
||||
Stroke="#5D5D5D" StrokeThickness="1"
|
||||
Width="16" Height="10"
|
||||
<Border Margin="2" CornerRadius="4"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||
MinWidth="28" MinHeight="28"
|
||||
Background="{Binding Color, Converter={StaticResource HexToBrush}}"
|
||||
ToolTip="{Binding Description}"
|
||||
ToolTipService.InitialShowDelay="150"
|
||||
ToolTipService.ShowDuration="30000"
|
||||
SnapsToDevicePixels="True">
|
||||
<TextBlock Text="{Binding Index}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
ToolTip="{Binding Description}"
|
||||
ToolTipService.InitialShowDelay="150"
|
||||
ToolTipService.ShowDuration="30000"
|
||||
SnapsToDevicePixels="True"/>
|
||||
<TextBlock Grid.Row="1" FontSize="12"
|
||||
Text="{Binding Index}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
Foreground="DimGray"/>
|
||||
</Grid>
|
||||
FontSize="11" FontWeight="SemiBold">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsActive}" Value="True">
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.UnlockPanelView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="380" d:DesignWidth="700">
|
||||
<!--
|
||||
Pump page §3.e Unlock inline view. DataContext = UnlockProgressViewModel
|
||||
(exposed from MainViewModel.CurrentUnlockVm). Hidden by the parent when
|
||||
the selected pump does not require unlock or the VM is null.
|
||||
-->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Background="#2B2929" BorderBrush="#111" BorderThickness="1"
|
||||
CornerRadius="4" Padding="18" Margin="6">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- title -->
|
||||
<RowDefinition Height="Auto"/> <!-- type label -->
|
||||
<RowDefinition Height="210"/> <!-- ring -->
|
||||
<RowDefinition Height="Auto"/> <!-- phase text -->
|
||||
<RowDefinition Height="Auto"/> <!-- progress bar -->
|
||||
<RowDefinition Height="Auto"/> <!-- result -->
|
||||
<RowDefinition Height="Auto"/> <!-- buttons -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{DynamicResource PumpSub.Unlock}"
|
||||
FontSize="15" FontWeight="SemiBold" Foreground="#EEE"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,4"/>
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Text="{Binding UnlockTypeLabel, Mode=OneWay}"
|
||||
FontSize="13" Foreground="#AAA"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,6"/>
|
||||
|
||||
<!-- Progress ring -->
|
||||
<Grid Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Ellipse Width="200" Height="200"
|
||||
Stroke="#4D4D4D" StrokeThickness="10"
|
||||
Fill="Transparent"/>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Dialog.Unlock.Progress}"
|
||||
FontSize="12" Foreground="#888"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,4"/>
|
||||
<TextBlock FontSize="60" FontFamily="Courier New"
|
||||
Foreground="White" HorizontalAlignment="Center">
|
||||
<TextBlock.Text>
|
||||
<Binding Path="Progress" Mode="OneWay"
|
||||
StringFormat="{}{0}%"/>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{Binding ElapsedTime, Mode=OneWay}"
|
||||
FontSize="16" FontFamily="Courier New"
|
||||
Foreground="#CCC" HorizontalAlignment="Center"
|
||||
Margin="0,2,0,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="3"
|
||||
Text="{Binding PhaseText, Mode=OneWay}"
|
||||
FontSize="16" Foreground="White"
|
||||
HorizontalAlignment="Center" Margin="0,6"/>
|
||||
|
||||
<ProgressBar Grid.Row="4"
|
||||
Value="{Binding Progress, Mode=OneWay}"
|
||||
Minimum="0" Maximum="100"
|
||||
Height="12" Margin="12,0"
|
||||
Foreground="#00EC00" Background="#3D3D3D"/>
|
||||
|
||||
<TextBlock Grid.Row="5"
|
||||
Text="{Binding ResultText, Mode=OneWay}"
|
||||
FontSize="22" FontWeight="Bold"
|
||||
HorizontalAlignment="Center" Margin="0,10,0,0"
|
||||
Visibility="{Binding IsComplete, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#FF5858"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSuccess}" Value="True">
|
||||
<Setter Property="Foreground" Value="#00EC00"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
|
||||
<!-- Only the cancel button is exposed inline; the panel cannot be "closed" here -->
|
||||
<StackPanel Grid.Row="6" Orientation="Horizontal"
|
||||
HorizontalAlignment="Center" Margin="0,14,0,0">
|
||||
<Button Content="{DynamicResource Common.Cancel}"
|
||||
Command="{Binding CancelCommand}"
|
||||
Width="110" Height="30"
|
||||
Foreground="White" FontWeight="Bold">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF5858"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Background" Value="#4D4D4D"/>
|
||||
<Setter Property="Foreground" Value="#888"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Inline unlock panel (Pump page §3.e). DataContext is the
|
||||
/// shared <c>UnlockProgressViewModel</c> also driving the floating
|
||||
/// progress dialog.
|
||||
/// </summary>
|
||||
public partial class UnlockPanelView : UserControl
|
||||
{
|
||||
public UnlockPanelView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Views/UserControls/UnlockSnackbarView.xaml
Normal file
115
Views/UserControls/UnlockSnackbarView.xaml
Normal file
@@ -0,0 +1,115 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.UserControls.UnlockSnackbarView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="80" d:DesignWidth="700">
|
||||
|
||||
<!-- DataContext = UnlockProgressViewModel (may be null — NullToVis collapses the border) -->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Visibility="{Binding Converter={StaticResource NullToVis}}"
|
||||
Style="{StaticResource SnackbarShell}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||
MinWidth="560" MaxWidth="860">
|
||||
|
||||
<DockPanel LastChildFill="True" Margin="16,10">
|
||||
|
||||
<!-- ── Leading state icon ────────────────────────────────────── -->
|
||||
<Grid DockPanel.Dock="Left" Width="30" Height="30" Margin="0,0,12,0">
|
||||
|
||||
<!-- In-progress spinner -->
|
||||
<ui:ProgressRing IsIndeterminate="True" Width="24" Height="24">
|
||||
<ui:ProgressRing.Style>
|
||||
<Style TargetType="ui:ProgressRing">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsComplete}" Value="True">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ui:ProgressRing.Style>
|
||||
</ui:ProgressRing>
|
||||
|
||||
<!-- Success check -->
|
||||
<ui:SymbolIcon Symbol="CheckmarkCircle24" FontSize="24"
|
||||
Foreground="{DynamicResource SystemFillColorSuccessBrush}">
|
||||
<ui:SymbolIcon.Style>
|
||||
<Style TargetType="ui:SymbolIcon">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSuccess}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ui:SymbolIcon.Style>
|
||||
</ui:SymbolIcon>
|
||||
|
||||
<!-- Failure/cancel X -->
|
||||
<ui:SymbolIcon Symbol="DismissCircle24" FontSize="24"
|
||||
Foreground="{DynamicResource SystemFillColorCriticalBrush}">
|
||||
<ui:SymbolIcon.Style>
|
||||
<Style TargetType="ui:SymbolIcon">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsComplete}" Value="True"/>
|
||||
<Condition Binding="{Binding IsSuccess}" Value="False"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</MultiDataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ui:SymbolIcon.Style>
|
||||
</ui:SymbolIcon>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Trailing buttons ───────────────────────────────────────── -->
|
||||
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center" Margin="12,0,0,0">
|
||||
<TextBlock Text="{Binding Progress, StringFormat={}{0}%}"
|
||||
FontFamily="Consolas" FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,0"/>
|
||||
|
||||
<ui:Button Content="{DynamicResource Common.Cancel}"
|
||||
Command="{Binding CancelCommand}"
|
||||
Appearance="Caution"
|
||||
Visibility="{Binding IsCancellable, Converter={StaticResource BoolToVis}}"
|
||||
Height="30" Padding="12,4"/>
|
||||
|
||||
<ui:Button Content="{DynamicResource Common.Dismiss}"
|
||||
Click="OnDismissClick"
|
||||
Appearance="Secondary"
|
||||
Visibility="{Binding IsComplete, Converter={StaticResource BoolToVis}}"
|
||||
Height="30" Padding="12,4"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── Middle: type + phase + progress bar ────────────────────── -->
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<DockPanel>
|
||||
<TextBlock DockPanel.Dock="Left"
|
||||
Text="{Binding UnlockTypeLabel}"
|
||||
FontWeight="SemiBold" FontSize="12"
|
||||
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="{Binding PhaseText}"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
</DockPanel>
|
||||
<ProgressBar Value="{Binding Progress, Mode=OneWay}"
|
||||
Minimum="0" Maximum="100" Height="3"
|
||||
Margin="0,4,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
54
Views/UserControls/UnlockSnackbarView.xaml.cs
Normal file
54
Views/UserControls/UnlockSnackbarView.xaml.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using HC_APTBS.ViewModels.Dialogs;
|
||||
|
||||
namespace HC_APTBS.Views.UserControls
|
||||
{
|
||||
public partial class UnlockSnackbarView : UserControl
|
||||
{
|
||||
private DispatcherTimer? _autoHideTimer;
|
||||
|
||||
public UnlockSnackbarView()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
}
|
||||
|
||||
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.OldValue is UnlockProgressViewModel oldVm)
|
||||
oldVm.PropertyChanged -= OnVmPropertyChanged;
|
||||
|
||||
if (e.NewValue is UnlockProgressViewModel newVm)
|
||||
newVm.PropertyChanged += OnVmPropertyChanged;
|
||||
}
|
||||
|
||||
private void OnVmPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName != nameof(UnlockProgressViewModel.IsSuccess)) return;
|
||||
if (DataContext is not UnlockProgressViewModel vm) return;
|
||||
|
||||
if (vm.IsSuccess == true)
|
||||
{
|
||||
_autoHideTimer?.Stop();
|
||||
_autoHideTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) };
|
||||
_autoHideTimer.Tick += (_, _) =>
|
||||
{
|
||||
_autoHideTimer!.Stop();
|
||||
if (vm.CloseCommand.CanExecute(null))
|
||||
vm.CloseCommand.Execute(null);
|
||||
};
|
||||
_autoHideTimer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDismissClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is UnlockProgressViewModel vm && vm.CloseCommand.CanExecute(null))
|
||||
vm.CloseCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user