feat: page-based navigation shell + Tests page wizard
Replace the monolithic MainWindow with a SelectedPage-driven shell (Dashboard / Pump / Bench / Tests / Results / Settings). The Tests page gets the Plan -> Preconditions -> Running -> Done wizard from ui-structure.md \u00a74, backed by a 7-item precondition gate and shared sub-views (PhaseCardView / TestSectionView / GraphicIndicatorView) extracted from the now-deleted monolithic TestPanelView. New VMs / views: - Tests wizard: TestPreconditions, PhaseCard, GraphicIndicator, TestSection, TestPlan, TestRunning, TestDone - Dashboard panels: DashboardConnection, DashboardReadings, DashboardAlarms, InterlockBanner, ResultHistory - Pump / bench panels: PumpIdentificationPanel, PumpLiveData, UnlockPanel, BenchDriveControl, BenchReadings, RelayBank, TemperatureControl, DtcList, AuthGate - Dialogs: generic ConfirmDialog, UserManageDialog, UserPromptDialog Supporting changes: - IsOilPumpOn exposed on MainViewModel for precondition evaluation - RequiresAuth added to TestDefinition (XML round-trip) - BipStatusDefinition + CompletedTestRun models - ~35 new Test.* localization keys (en + es) - Settings moved from modal dialog to full page - Pause / Retry / Skip stubs in TestRunningView; full spec in docs/gap-test-running-controls.md for follow-up implementation - docs/ui-structure.md captures the wizard design Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
66
Views/Pages/BenchPage.xaml
Normal file
66
Views/Pages/BenchPage.xaml
Normal file
@@ -0,0 +1,66 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.Pages.BenchPage"
|
||||
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="900" d:DesignWidth="1280">
|
||||
<!--
|
||||
Bench page — HMI-style manual hardware operation.
|
||||
DataContext = BenchPageViewModel.
|
||||
Three zones:
|
||||
A. Live readings (LCD panel + encoder angles)
|
||||
B. Live plots (Q flows + pressure traces)
|
||||
C. Controls (drive, temperature, relay bank)
|
||||
Interlock banner spans the page above zone contents when triggered.
|
||||
-->
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<Grid Margin="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- interlock banner -->
|
||||
<RowDefinition Height="*"/> <!-- main content -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Interlock banner: hidden unless InterlockBannerViewModel raises a condition -->
|
||||
<uc:InterlockBannerView Grid.Row="0" DataContext="{Binding Interlock}"/>
|
||||
|
||||
<!-- Main content: 3 columns -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="400"/> <!-- Zone A: readings + angles -->
|
||||
<ColumnDefinition Width="*"/> <!-- Zone B: live plots -->
|
||||
<ColumnDefinition Width="210"/> <!-- Zone C: controls -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- ── Zone A: readings + encoder angles ──────────────────── -->
|
||||
<StackPanel Grid.Column="0" Margin="0,0,6,0">
|
||||
<uc:BenchReadingsView/>
|
||||
<uc:AngleDisplayView DataContext="{Binding AngleDisplay}"
|
||||
Margin="0,6,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── Zone B: live plots (flows + pressure) ──────────────── -->
|
||||
<StackPanel Grid.Column="1" Margin="0,0,6,0">
|
||||
<uc:FlowmeterChartView DataContext="{Binding FlowmeterChart.Delivery}"/>
|
||||
<uc:FlowmeterChartView DataContext="{Binding FlowmeterChart.Over}"
|
||||
Margin="0,4,0,0"/>
|
||||
<uc:FlowmeterChartView DataContext="{Binding PressureTrace.P1}"
|
||||
Margin="0,4,0,0"/>
|
||||
<uc:FlowmeterChartView DataContext="{Binding PressureTrace.P2}"
|
||||
Margin="0,4,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── Zone C: stacked control panels ─────────────────────── -->
|
||||
<StackPanel Grid.Column="2">
|
||||
<uc:BenchDriveControlView/>
|
||||
<uc:TemperatureControlView DataContext="{Binding TempControl}"
|
||||
Margin="0,10,0,0"/>
|
||||
<uc:RelayBankView DataContext="{Binding RelayBank}"
|
||||
Margin="0,10,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
16
Views/Pages/BenchPage.xaml.cs
Normal file
16
Views/Pages/BenchPage.xaml.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// Bench navigation page. DataContext is expected to be a
|
||||
/// <see cref="HC_APTBS.ViewModels.Pages.BenchPageViewModel"/>.
|
||||
/// </summary>
|
||||
public partial class BenchPage : UserControl
|
||||
{
|
||||
public BenchPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
241
Views/Pages/DashboardPage.xaml
Normal file
241
Views/Pages/DashboardPage.xaml
Normal file
@@ -0,0 +1,241 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.Pages.DashboardPage"
|
||||
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="700" d:DesignWidth="980">
|
||||
<!--
|
||||
Dashboard — operator "at a glance" landing page.
|
||||
DataContext: DashboardPageViewModel. Read-first. Only Start / Stop / E-Stop are interactive.
|
||||
-->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
|
||||
<!-- Section card style -->
|
||||
<Style x:Key="DashCard" TargetType="Border">
|
||||
<Setter Property="Background" Value="#FAFAFA"/>
|
||||
<Setter Property="BorderBrush" Value="#DDD"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DashHeader" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="#333"/>
|
||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Margin="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/> <!-- footer: quick actions -->
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="340"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- ── Left column: readings ───────────────────────────────────────── -->
|
||||
<Border Grid.Row="0" Grid.Column="0" Style="{StaticResource DashCard}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{DynamicResource Dashboard.Readings}" Style="{StaticResource DashHeader}"/>
|
||||
<uc:DashboardReadingsView/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- ── Right column: connections + test summary + alarms ───────────── -->
|
||||
<Grid Grid.Row="0" Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Connections -->
|
||||
<Border Grid.Row="0" Grid.Column="0" Style="{StaticResource DashCard}">
|
||||
<uc:DashboardConnectionView/>
|
||||
</Border>
|
||||
|
||||
<!-- Test summary -->
|
||||
<Border Grid.Row="0" Grid.Column="1" Style="{StaticResource DashCard}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{DynamicResource Dashboard.TestSummary}" Style="{StaticResource DashHeader}"/>
|
||||
|
||||
<!-- Active test view (when running) -->
|
||||
<StackPanel Visibility="{Binding Root.IsTestRunning, Converter={StaticResource BoolToVis}}">
|
||||
<Grid Margin="0,2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{DynamicResource Dashboard.TestActive}" Foreground="#555" FontSize="12"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding Root.TestPanel.TestName}"
|
||||
FontWeight="SemiBold" FontSize="13" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
<Grid Margin="0,2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{DynamicResource Dashboard.TestPhase}" Foreground="#555" FontSize="12"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding Root.CurrentPhaseName}"
|
||||
FontFamily="Consolas" FontSize="13" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
<TextBlock Text="{Binding Root.VerboseStatus}" FontStyle="Italic"
|
||||
Foreground="#666" FontSize="11" Margin="0,6,0,0"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Idle view (last result or "no test run") -->
|
||||
<StackPanel>
|
||||
<StackPanel.Style>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.IsTestRunning}" Value="True">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Style>
|
||||
|
||||
<TextBlock Text="{DynamicResource Dashboard.NoTestRunning}"
|
||||
Foreground="#888" FontStyle="Italic" FontSize="12"/>
|
||||
|
||||
<Border Margin="0,8,0,0" Padding="8,4" CornerRadius="3"
|
||||
HorizontalAlignment="Left">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="#D62828"/>
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding Root.IsTestSaved}" Value="False"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</MultiDataTrigger>
|
||||
<DataTrigger Binding="{Binding Root.LastTestSuccess}" Value="True">
|
||||
<Setter Property="Background" Value="#26C200"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Foreground="White" FontWeight="Bold" FontSize="12">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.LastTestFail}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Root.LastTestSuccess}" Value="True">
|
||||
<Setter Property="Text" Value="{DynamicResource Dashboard.LastTestPass}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Alarms (spans both columns of the right grid) -->
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Style="{StaticResource DashCard}">
|
||||
<DockPanel>
|
||||
<TextBlock DockPanel.Dock="Top" Text="{DynamicResource Dashboard.Alarms}"
|
||||
Style="{StaticResource DashHeader}"/>
|
||||
|
||||
<!-- "System OK" banner when no alarms -->
|
||||
<Border Background="#26C200" CornerRadius="3" Padding="10,6"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
Visibility="{Binding Alarms.IsClear, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock Text="{DynamicResource Dashboard.AlarmsNone}"
|
||||
Foreground="White" FontWeight="Bold" FontSize="12"/>
|
||||
</Border>
|
||||
|
||||
<!-- Active alarm list -->
|
||||
<ItemsControl ItemsSource="{Binding Alarms.ActiveAlarms}">
|
||||
<ItemsControl.Style>
|
||||
<Style TargetType="ItemsControl">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Alarms.IsClear}" Value="True">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ItemsControl.Style>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Margin="0,2" Padding="8,4" CornerRadius="3">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="#FFB020"/> <!-- warning -->
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsCritical}" Value="True">
|
||||
<Setter Property="Background" Value="#D62828"/> <!-- critical -->
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="●" Foreground="White" FontSize="14" VerticalAlignment="Center" Margin="0,0,6,0"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding Description}"
|
||||
Foreground="White" FontWeight="SemiBold" FontSize="12"
|
||||
VerticalAlignment="Center" TextWrapping="Wrap"/>
|
||||
<TextBlock Grid.Column="2" Foreground="#FFF" FontSize="11" FontFamily="Consolas"
|
||||
VerticalAlignment="Center" Margin="6,0,0,0">
|
||||
<Run Text="bit "/><Run Text="{Binding Bit, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- ── Footer: quick actions ───────────────────────────────────────── -->
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
Background="#F0F0F0" BorderBrush="#CCC" BorderThickness="0,1,0,0"
|
||||
Padding="8" Margin="4,4,4,4">
|
||||
<DockPanel LastChildFill="False">
|
||||
<Button DockPanel.Dock="Left"
|
||||
Content="{DynamicResource Dashboard.Action.StartTest}"
|
||||
Command="{Binding Root.StartTestCommand}"
|
||||
Height="44" MinWidth="140" FontSize="13" FontWeight="Bold"
|
||||
Foreground="DarkGreen" Margin="0,0,6,0"
|
||||
ToolTipService.ShowOnDisabled="True"
|
||||
ToolTip="{DynamicResource Dashboard.Action.StartTest.Tip}"/>
|
||||
|
||||
<Button DockPanel.Dock="Left"
|
||||
Content="{DynamicResource Dashboard.Action.Stop}"
|
||||
Command="{Binding Root.StopTestCommand}"
|
||||
Height="44" MinWidth="120" FontSize="13" FontWeight="Bold"
|
||||
Foreground="DarkRed" Margin="0,0,6,0"/>
|
||||
|
||||
<!-- E-Stop pinned right, red, always visible -->
|
||||
<Button DockPanel.Dock="Right"
|
||||
Content="{DynamicResource Dashboard.Action.EmergencyStop}"
|
||||
Command="{Binding Root.EmergencyStopCommand}"
|
||||
Height="44" MinWidth="200" FontSize="14" FontWeight="Bold"
|
||||
Foreground="White" Background="#D62828" BorderBrush="#8B0000"
|
||||
BorderThickness="2"/>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
16
Views/Pages/DashboardPage.xaml.cs
Normal file
16
Views/Pages/DashboardPage.xaml.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// Dashboard navigation page. DataContext is expected to be a
|
||||
/// <see cref="HC_APTBS.ViewModels.Pages.DashboardPageViewModel"/>.
|
||||
/// </summary>
|
||||
public partial class DashboardPage : UserControl
|
||||
{
|
||||
public DashboardPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
288
Views/Pages/PumpPage.xaml
Normal file
288
Views/Pages/PumpPage.xaml
Normal file
@@ -0,0 +1,288 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.Pages.PumpPage"
|
||||
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"
|
||||
xmlns:vm="clr-namespace:HC_APTBS.ViewModels.Pages"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="780" d:DesignWidth="1100">
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
<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.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- banners -->
|
||||
<RowDefinition Height="*"/> <!-- body -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════════
|
||||
Banners: K-Line session + no pump selected
|
||||
══════════════════════════════════════════════════════════════ -->
|
||||
<StackPanel 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
|
||||
══════════════════════════════════════════════════════════════ -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</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}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{DynamicResource PumpSub.Adaptation}"
|
||||
Style="{StaticResource SubNavText}"/>
|
||||
<TextBlock Text=" 🔒" FontSize="11"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding DataContext.AdaptationAuth.IsAuthenticated,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
Value="True">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</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>
|
||||
|
||||
<!-- ── Sub-page content ───────────────────────────────────── -->
|
||||
<TabControl Grid.Column="1"
|
||||
Style="{StaticResource HiddenTabsTabControl}"
|
||||
SelectedIndex="{Binding SelectedSubPage, Converter={StaticResource EnumToInt}}">
|
||||
|
||||
<!-- 3a Identification -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<uc:PumpIdentificationPanelView
|
||||
DataContext="{Binding Identification}"/>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<!-- 3b DTCs -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<uc:DtcListView DataContext="{Binding DtcList}"/>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<!-- 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 (auth-gated) -->
|
||||
<TabItem>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<uc:AuthGateView DataContext="{Binding AdaptationAuth}">
|
||||
<uc:AuthGateView.GatedContent>
|
||||
<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 DataContext.DfiViewModel,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
|
||||
<Separator Margin="0,10"/>
|
||||
<uc:PumpControlView DataContext="{Binding DataContext.PumpControl,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</uc:AuthGateView.GatedContent>
|
||||
</uc:AuthGateView>
|
||||
</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>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
16
Views/Pages/PumpPage.xaml.cs
Normal file
16
Views/Pages/PumpPage.xaml.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// Pump navigation page. DataContext is expected to be a
|
||||
/// <see cref="HC_APTBS.ViewModels.Pages.PumpPageViewModel"/>.
|
||||
/// </summary>
|
||||
public partial class PumpPage : UserControl
|
||||
{
|
||||
public PumpPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
162
Views/Pages/ResultsPage.xaml
Normal file
162
Views/Pages/ResultsPage.xaml
Normal file
@@ -0,0 +1,162 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.Pages.ResultsPage"
|
||||
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="700" d:DesignWidth="1100">
|
||||
<!--
|
||||
Results — review completed test runs, edit observations, export PDF.
|
||||
DataContext: ResultsPageViewModel. No live hardware data on this page.
|
||||
-->
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
|
||||
<Style x:Key="DashCard" TargetType="Border">
|
||||
<Setter Property="Background" Value="#FAFAFA"/>
|
||||
<Setter Property="BorderBrush" Value="#DDD"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DashHeader" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="#333"/>
|
||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Margin="6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="320"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- ── Left: history list ─────────────────────────────────────────── -->
|
||||
<Border Grid.Column="0" Style="{StaticResource DashCard}">
|
||||
<uc:ResultHistoryView/>
|
||||
</Border>
|
||||
|
||||
<!-- ── Right: detail pane ──────────────────────────────────────────── -->
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- header -->
|
||||
<RowDefinition Height="*"/> <!-- results table -->
|
||||
<RowDefinition Height="Auto"/> <!-- observations -->
|
||||
<RowDefinition Height="Auto"/> <!-- actions -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Selected-run header -->
|
||||
<Border Grid.Row="0" Style="{StaticResource DashCard}"
|
||||
Visibility="{Binding SelectedRun, Converter={StaticResource BoolToVis}}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Style="{StaticResource DashHeader}">
|
||||
<Run Text="{Binding SelectedRun.PumpModel, Mode=OneWay}"/>
|
||||
<Run Text=" · "/>
|
||||
<Run Text="{Binding SelectedRun.PumpSerial, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
<TextBlock FontSize="11" Foreground="#666"
|
||||
Text="{Binding SelectedRun.CompletedAt, StringFormat='{}{0:dd MMM yyyy HH:mm:ss}'}"/>
|
||||
<TextBlock FontSize="11" Foreground="#666" Margin="0,2,0,0"
|
||||
Text="{Binding SelectedRun.TestNames}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Overall verdict pill -->
|
||||
<Border Grid.Column="1" Padding="8,3" CornerRadius="3"
|
||||
VerticalAlignment="Center">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="#B71C1C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectedRun.OverallPassed}" Value="True">
|
||||
<Setter Property="Background" Value="#2E7D32"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding SelectedRun.Interrupted}" Value="True">
|
||||
<Setter Property="Background" Value="#FFB020"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Foreground="White" FontSize="13" FontWeight="Bold">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{DynamicResource Common.Fail}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectedRun.OverallPassed}" Value="True">
|
||||
<Setter Property="Text" Value="{DynamicResource Common.Pass}"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding SelectedRun.Interrupted}" Value="True">
|
||||
<Setter Property="Text" Value="{DynamicResource Results.InterruptedLabel}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Embedded ResultDisplayView — bound to the page's Detail VM -->
|
||||
<Border Grid.Row="1" Style="{StaticResource DashCard}"
|
||||
Visibility="{Binding SelectedRun, Converter={StaticResource BoolToVis}}">
|
||||
<uc:ResultDisplayView DataContext="{Binding Detail}"/>
|
||||
</Border>
|
||||
|
||||
<!-- Observations / notes -->
|
||||
<Border Grid.Row="2" Style="{StaticResource DashCard}"
|
||||
Visibility="{Binding SelectedRun, Converter={StaticResource BoolToVis}}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{DynamicResource Results.ObservationsLabel}"
|
||||
Style="{StaticResource DashHeader}"/>
|
||||
<TextBox Text="{Binding SelectedRun.Observations, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
AcceptsReturn="True" TextWrapping="Wrap"
|
||||
Height="80" VerticalScrollBarVisibility="Auto"
|
||||
FontSize="12"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Action row -->
|
||||
<Border Grid.Row="3" Background="#F0F0F0" BorderBrush="#CCC"
|
||||
BorderThickness="0,1,0,0" Padding="8" Margin="4,4,4,4"
|
||||
Visibility="{Binding SelectedRun, Converter={StaticResource BoolToVis}}">
|
||||
<DockPanel LastChildFill="False">
|
||||
<Button DockPanel.Dock="Right"
|
||||
Content="{DynamicResource Results.ExportButton}"
|
||||
Command="{Binding ExportPdfCommand}"
|
||||
Height="36" MinWidth="160" FontSize="13" FontWeight="Bold"
|
||||
Foreground="White" Background="#1976D2" BorderBrush="#0D47A1"
|
||||
BorderThickness="1"/>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Empty-state when no selection (covers rows 0-3) -->
|
||||
<Border Grid.Row="0" Grid.RowSpan="4"
|
||||
VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource DashCard}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectedRun}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{DynamicResource Results.NoSelection}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
FontSize="13" Foreground="#888" FontStyle="Italic"
|
||||
TextWrapping="Wrap" TextAlignment="Center"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
14
Views/Pages/ResultsPage.xaml.cs
Normal file
14
Views/Pages/ResultsPage.xaml.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// Results navigation page (§5 in <c>docs/ui-structure.md</c>).
|
||||
/// Review, compare, and export completed test runs. DataContext must be a
|
||||
/// <see cref="ViewModels.Pages.ResultsPageViewModel"/>.
|
||||
/// </summary>
|
||||
public partial class ResultsPage : UserControl
|
||||
{
|
||||
public ResultsPage() => InitializeComponent();
|
||||
}
|
||||
}
|
||||
342
Views/Pages/SettingsPage.xaml
Normal file
342
Views/Pages/SettingsPage.xaml
Normal file
@@ -0,0 +1,342 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.Pages.SettingsPage"
|
||||
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"
|
||||
FontFamily="Ebrima"
|
||||
Background="#FFEDEDED"
|
||||
d:DesignHeight="700" d:DesignWidth="980">
|
||||
<!--
|
||||
Settings page — form-based, grouped, tabbed.
|
||||
DataContext: SettingsPageViewModel. Changes only apply on Save.
|
||||
-->
|
||||
<DockPanel Margin="12">
|
||||
|
||||
<!-- ── Bottom Save/Discard bar ───────────────────────────────────── -->
|
||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal"
|
||||
HorizontalAlignment="Right" Margin="0,12,0,0">
|
||||
<Button Content="{DynamicResource Common.Accept}" Width="90" Height="28"
|
||||
Margin="0,0,8,0" Command="{Binding SaveCommand}" IsDefault="True"/>
|
||||
<Button Content="{DynamicResource Common.Cancel}" Width="90" Height="28"
|
||||
Command="{Binding DiscardCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ── Tab control ───────────────────────────────────────────────── -->
|
||||
<TabControl>
|
||||
|
||||
<!-- ══ General ══════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.General}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.Language}"
|
||||
FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<ComboBox ItemsSource="{Binding AvailableLanguages}"
|
||||
SelectedItem="{Binding SelectedLanguage}"
|
||||
Width="120" HorizontalAlignment="Left"/>
|
||||
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.DaysKeepLogs}"
|
||||
FontWeight="SemiBold" Margin="0,16,0,4"/>
|
||||
<TextBox Text="{Binding DaysKeepLogs, UpdateSourceTrigger=LostFocus}"
|
||||
Width="80" HorizontalAlignment="Left"/>
|
||||
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.UsersHeader}"
|
||||
FontWeight="SemiBold" Margin="0,16,0,4"/>
|
||||
<Button Content="{DynamicResource Dialog.Settings.ManageUsers}"
|
||||
Command="{Binding ManageUsersCommand}"
|
||||
Width="200" Height="26" HorizontalAlignment="Left"/>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<!-- ══ Safety ═══════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.Safety}">
|
||||
<Grid Margin="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Dialog.Settings.TempMax}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding TempMax, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{DynamicResource Dialog.Settings.TempMin}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding TempMin, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="{DynamicResource Dialog.Settings.SecurityRpmLimit}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding SecurityRpmLimit, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{DynamicResource Dialog.Settings.MaxPressureBar}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding MaxPressureBar, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="{DynamicResource Dialog.Settings.ToleranceUp}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding ToleranceUpExtension, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Text="{DynamicResource Dialog.Settings.TolerancePfp}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding TolerancePfpExtension, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<CheckBox Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
Content="{DynamicResource Dialog.Settings.IgnoreTin}"
|
||||
IsChecked="{Binding DefaultIgnoreTin}" Margin="0,4,0,0"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<!-- ══ PID ══════════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.Pid}">
|
||||
<Grid Margin="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Dialog.Settings.PidP}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding PidP, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{DynamicResource Dialog.Settings.PidI}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding PidI, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="{DynamicResource Dialog.Settings.PidD}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding PidD, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{DynamicResource Dialog.Settings.PidLoopMs}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding PidLoopMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<!-- ══ Motor ════════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.Motor}">
|
||||
<DockPanel Margin="16">
|
||||
<!-- Top: motor parameters -->
|
||||
<Grid DockPanel.Dock="Top">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Dialog.Settings.EncoderRes}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding EncoderResolution, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{DynamicResource Dialog.Settings.VoltMaxRpm}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding VoltageForMaxRpm, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="{DynamicResource Dialog.Settings.MaxRpm}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding MaxRpm, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<CheckBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
Content="{DynamicResource Dialog.Settings.RightRelay}"
|
||||
IsChecked="{Binding RightRelayValue}" Margin="0,4,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<!-- RPM-Voltage relation table -->
|
||||
<GroupBox Margin="0,12,0,0">
|
||||
<GroupBox.Header>
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.Relations}" FontWeight="SemiBold"/>
|
||||
</GroupBox.Header>
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" Margin="0,4,0,0">
|
||||
<Button Content="{DynamicResource Dialog.Settings.AddRow}"
|
||||
Command="{Binding AddRelationCommand}"
|
||||
Width="75" Margin="0,0,8,0"/>
|
||||
<Button Content="{DynamicResource Dialog.Settings.RemoveRow}"
|
||||
Command="{Binding RemoveRelationCommand}"
|
||||
CommandParameter="{Binding SelectedItem, ElementName=RelationsGrid}"
|
||||
Width="75"/>
|
||||
</StackPanel>
|
||||
<DataGrid x:Name="RelationsGrid"
|
||||
ItemsSource="{Binding Relations}"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
CanUserDeleteRows="False"
|
||||
SelectionMode="Single"
|
||||
HeadersVisibility="Column"
|
||||
GridLinesVisibility="Horizontal"
|
||||
MinHeight="120">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.RelRpm}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.HeaderTemplate>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Rpm}" VerticalAlignment="Center" Margin="4,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Text="{Binding Rpm, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.RelVoltage}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.HeaderTemplate>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Voltage}" VerticalAlignment="Center" Margin="4,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Text="{Binding Voltage, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
<!-- ══ Report ═══════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.Report}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.CompanyName}"
|
||||
FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<TextBox Text="{Binding CompanyName, UpdateSourceTrigger=LostFocus}"/>
|
||||
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.CompanyInfo}"
|
||||
FontWeight="SemiBold" Margin="0,12,0,4"/>
|
||||
<TextBox Text="{Binding CompanyInfo, UpdateSourceTrigger=LostFocus}"
|
||||
TextWrapping="Wrap" AcceptsReturn="True" Height="80"
|
||||
VerticalScrollBarVisibility="Auto"/>
|
||||
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.ReportLogo}"
|
||||
FontWeight="SemiBold" Margin="0,12,0,4"/>
|
||||
<DockPanel>
|
||||
<Button DockPanel.Dock="Right" Content="..." Width="30"
|
||||
Margin="4,0,0,0" Command="{Binding BrowseLogoCommand}"/>
|
||||
<TextBox Text="{Binding ReportLogoPath, UpdateSourceTrigger=LostFocus}"
|
||||
IsReadOnly="True" Background="#F0F0F0"/>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<!-- ══ K-Line ═══════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.KLine}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.KLinePort}"
|
||||
FontWeight="SemiBold" Margin="0,0,0,4"/>
|
||||
<DockPanel>
|
||||
<Button DockPanel.Dock="Right"
|
||||
Content="{DynamicResource Dialog.Settings.RefreshPorts}"
|
||||
Margin="8,0,0,0" Width="80"
|
||||
Command="{Binding RefreshPortsCommand}"/>
|
||||
<ComboBox ItemsSource="{Binding AvailablePorts}"
|
||||
SelectedItem="{Binding SelectedKLinePort}"
|
||||
IsEditable="True"
|
||||
Text="{Binding SelectedKLinePort, UpdateSourceTrigger=LostFocus}"/>
|
||||
</DockPanel>
|
||||
<TextBlock Text="{DynamicResource Dialog.Settings.KLineHint}"
|
||||
FontStyle="Italic" Foreground="Gray" Margin="0,8,0,0"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<!-- ══ Advanced ═════════════════════════════════════════════════ -->
|
||||
<TabItem Header="{DynamicResource Dialog.Settings.Tab.Advanced}">
|
||||
<Grid Margin="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Dialog.Settings.RefreshBench}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding RefreshBenchInterfaceMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{DynamicResource Dialog.Settings.RefreshReading}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding RefreshWhileReadingMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="{DynamicResource Dialog.Settings.RefreshCanBus}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding RefreshCanBusReadMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{DynamicResource Dialog.Settings.RefreshPumpReq}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding RefreshPumpRequestMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="{DynamicResource Dialog.Settings.RefreshPumpParams}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding RefreshPumpParamsMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Text="{DynamicResource Dialog.Settings.BlinkInterval}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding BlinkIntervalMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Text="{DynamicResource Dialog.Settings.FlasherInterval}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,6"/>
|
||||
<TextBox Grid.Row="6" Grid.Column="1" Text="{Binding FlasherIntervalMs, UpdateSourceTrigger=LostFocus}"
|
||||
Margin="0,0,0,6"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
17
Views/Pages/SettingsPage.xaml.cs
Normal file
17
Views/Pages/SettingsPage.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings navigation page. Hosts grouped configuration forms (General,
|
||||
/// Safety, PID, Motor, Report, K-Line, Advanced). DataContext is
|
||||
/// <see cref="HC_APTBS.ViewModels.Pages.SettingsPageViewModel"/>.
|
||||
/// </summary>
|
||||
public partial class SettingsPage : UserControl
|
||||
{
|
||||
public SettingsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
204
Views/Pages/TestsPage.xaml
Normal file
204
Views/Pages/TestsPage.xaml
Normal file
@@ -0,0 +1,204 @@
|
||||
<UserControl x:Class="HC_APTBS.Views.Pages.TestsPage"
|
||||
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:models="clr-namespace:HC_APTBS.Models"
|
||||
xmlns:uc="clr-namespace:HC_APTBS.Views.UserControls"
|
||||
xmlns:vm="clr-namespace:HC_APTBS.ViewModels"
|
||||
xmlns:vmp="clr-namespace:HC_APTBS.ViewModels.Pages"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="800" d:DesignWidth="1000"
|
||||
d:DataContext="{d:DesignInstance Type=vmp:TestsPageViewModel, IsDesignTimeCreatable=False}">
|
||||
<!--
|
||||
Plan → Preconditions → Running → Done wizard (ui-structure.md §4).
|
||||
DataContext: TestsPageViewModel.
|
||||
Top row: 4-pill stepper. Middle: ContentControl routing CurrentStateVm
|
||||
through typed DataTemplates. Bottom: wizard footer with Back / Next.
|
||||
-->
|
||||
<UserControl.Resources>
|
||||
<!-- Step → View mappings -->
|
||||
<DataTemplate DataType="{x:Type vmp:PlanStateViewModel}">
|
||||
<uc:TestPlanView DataContext="{Binding TestPanel}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type vm:TestPreconditionsViewModel}">
|
||||
<uc:TestPreconditionsView/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type vmp:RunningStateViewModel}">
|
||||
<uc:TestRunningView DataContext="{Binding TestPanel}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type vmp:TestsPageViewModel}">
|
||||
<uc:TestDoneView/>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Stepper pill style -->
|
||||
<Style x:Key="StepPillStyle" TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="12"/>
|
||||
<Setter Property="Padding" Value="14,4"/>
|
||||
<Setter Property="Margin" Value="0,0,6,0"/>
|
||||
<Setter Property="Background" Value="#ECEFF1"/>
|
||||
<Setter Property="BorderBrush" Value="#CFD8DC"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Wizard stepper -->
|
||||
<Border Background="White" BorderBrush="#DDD" BorderThickness="0,0,0,1" Padding="10,8">
|
||||
<ItemsControl>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
<Border Style="{StaticResource StepPillStyle}">
|
||||
<Border.Resources>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StepPillStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Plan}">
|
||||
<Setter Property="Background" Value="#1565C0"/>
|
||||
<Setter Property="BorderBrush" Value="#0D47A1"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Resources>
|
||||
<TextBlock Text="{DynamicResource Test.Wizard.Plan}" FontSize="12">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#455A64"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Plan}">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource StepPillStyle}">
|
||||
<Border.Resources>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StepPillStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Preconditions}">
|
||||
<Setter Property="Background" Value="#1565C0"/>
|
||||
<Setter Property="BorderBrush" Value="#0D47A1"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Resources>
|
||||
<TextBlock Text="{DynamicResource Test.Wizard.Preconditions}" FontSize="12">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#455A64"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Preconditions}">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource StepPillStyle}">
|
||||
<Border.Resources>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StepPillStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Running}">
|
||||
<Setter Property="Background" Value="#1565C0"/>
|
||||
<Setter Property="BorderBrush" Value="#0D47A1"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Resources>
|
||||
<TextBlock Text="{DynamicResource Test.Wizard.Running}" FontSize="12">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#455A64"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Running}">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource StepPillStyle}">
|
||||
<Border.Resources>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StepPillStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Done}">
|
||||
<Setter Property="Background" Value="#1565C0"/>
|
||||
<Setter Property="BorderBrush" Value="#0D47A1"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Resources>
|
||||
<TextBlock Text="{DynamicResource Test.Wizard.Done}" FontSize="12">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#455A64"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CurrentState}"
|
||||
Value="{x:Static models:TestFlowState.Done}">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</ItemsControl>
|
||||
</Border>
|
||||
|
||||
<!-- Current step body -->
|
||||
<ContentControl Grid.Row="1" Content="{Binding CurrentStateVm}"/>
|
||||
|
||||
<!-- Wizard footer: Back / Next -->
|
||||
<Border Grid.Row="2" Padding="10,8"
|
||||
Background="White" BorderBrush="#DDD" BorderThickness="0,1,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="0"
|
||||
Content="{DynamicResource Test.Wizard.Back}"
|
||||
Command="{Binding BackCommand}"
|
||||
Padding="16,6" FontSize="12"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Content="{DynamicResource Test.Wizard.Next}"
|
||||
Command="{Binding NextCommand}"
|
||||
Padding="16,6" FontSize="12"
|
||||
FontWeight="SemiBold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
16
Views/Pages/TestsPage.xaml.cs
Normal file
16
Views/Pages/TestsPage.xaml.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HC_APTBS.Views.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests navigation page. DataContext is expected to be a
|
||||
/// <see cref="HC_APTBS.ViewModels.Pages.TestsPageViewModel"/>.
|
||||
/// </summary>
|
||||
public partial class TestsPage : UserControl
|
||||
{
|
||||
public TestsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user