Files
XplorePlane/XP.Hardware.PLC/Views/PlcTestBenchWindow.xaml
T

245 lines
16 KiB
XML

<Window x:Class="XP.Hardware.PLC.Views.PlcTestBenchWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:XP.Hardware.PLC.ViewModels"
Title="PLC 测试工具 | PLC Test Bench"
Width="1000" Height="700"
MinWidth="900" MinHeight="650"
WindowStartupLocation="CenterScreen"
Background="#FFF5F5F5">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
<!-- 日志条目数据模板 | Log entry data template -->
<DataTemplate DataType="{x:Type vm:LogEntry}">
<TextBlock Text="{Binding DisplayText}" FontFamily="Consolas" FontSize="12" Margin="2,1">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="#FF333333"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Level}" Value="WARN">
<Setter Property="Foreground" Value="#FFE68A00"/>
</DataTrigger>
<DataTrigger Binding="{Binding Level}" Value="ERROR">
<Setter Property="Foreground" Value="#FFD32F2F"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Window.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="200"/>
</Grid.RowDefinitions>
<!-- 顶部:连接配置区 | Top: Connection config area -->
<GroupBox Grid.Row="0" Header="连接配置 | Connection Config" Foreground="#FF333333" Margin="0,0,0,5"
BorderBrush="#FFBDBDBD" Background="#FFFFFFFF">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="IP:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,5,0"/>
<TextBox Grid.Column="1" Text="{Binding IpAddress, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Grid.Column="2" Text="端口:" VerticalAlignment="Center" Foreground="#FF333333" Margin="5,0,5,0"/>
<TextBox Grid.Column="3" Text="{Binding Port, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Grid.Column="4" Text="机架:" VerticalAlignment="Center" Foreground="#FF333333" Margin="5,0,5,0"/>
<TextBox Grid.Column="5" Text="{Binding Rack, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Grid.Column="6" Text="槽位:" VerticalAlignment="Center" Foreground="#FF333333" Margin="5,0,5,0"/>
<TextBox Grid.Column="7" Text="{Binding Slot, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Grid.Column="8" Text="类型:" VerticalAlignment="Center" Foreground="#FF333333" Margin="5,0,5,0"/>
<ComboBox Grid.Column="9" ItemsSource="{Binding PlcTypes}" SelectedItem="{Binding SelectedPlcType}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<!-- 连接/断开按钮和状态 | Connect/Disconnect buttons and status -->
<StackPanel Grid.Column="10" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="连接" Command="{Binding ConnectCommand}" Width="60" Margin="0,0,5,0" Padding="5,3"/>
<Button Content="断开" Command="{Binding DisconnectCommand}" Width="60" Margin="0,0,5,0" Padding="5,3"/>
<!-- 状态指示灯 | Status indicator -->
<Ellipse Width="14" Height="14" VerticalAlignment="Center" Margin="5,0,5,0">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="#FFBDBDBD"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsConnected}" Value="True">
<Setter Property="Fill" Value="#FF4CAF50"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock Text="{Binding StatusText}" VerticalAlignment="Center" Foreground="#FF666666" FontSize="11" MaxWidth="200" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Grid>
</GroupBox>
<!-- 中部:单点读写区 + 批量读取区 | Middle: Single point R/W + Batch read -->
<Grid Grid.Row="1" Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧:单点读写区 | Left: Single point read/write -->
<GroupBox Grid.Column="0" Header="单点读写 | Single Point R/W" Foreground="#FF333333" Margin="0,0,3,0"
BorderBrush="#FFBDBDBD" Background="#FFFFFFFF">
<StackPanel Margin="8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<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="地址:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,8,5"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding PointAddress, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,0,5"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="类型:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,8,5"/>
<ComboBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding DataTypes}" SelectedItem="{Binding SelectedDataType}" VerticalContentAlignment="Center" Margin="0,0,0,5"/>
<!-- 字符串长度行(仅 String 类型可见)| String length row (visible only for String type) -->
<TextBlock Grid.Row="2" Grid.Column="0" Text="字符串长度:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,8,5"
Visibility="{Binding IsStringType, Converter={StaticResource BoolToVisConverter}}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding StringLength, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,0,5"
Visibility="{Binding IsStringType, Converter={StaticResource BoolToVisConverter}}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="读取结果:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,8,5"/>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding ReadResult, Mode=OneWay}" IsReadOnly="True" VerticalContentAlignment="Center" Background="#FFF0F0F0" Foreground="#FF1B5E20" Margin="0,0,0,5"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="写入值:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,8,5"/>
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding WriteValue, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,0,5"/>
</Grid>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Button Content="读取" Command="{Binding ReadCommand}" Width="70" Margin="0,0,5,0" Padding="5,3"/>
<Button Content="写入" Command="{Binding WriteCommand}" Width="70" Margin="0,0,5,0" Padding="5,3"/>
<Button Content="切换 (Toggle)" Command="{Binding ToggleBoolCommand}" Width="100" Margin="0,0,5,0" Padding="5,3"
Visibility="{Binding IsBoolType, Converter={StaticResource BoolToVisConverter}}"/>
<Button Content="连续读取" Command="{Binding StartContinuousReadCommand}" Width="80" Margin="0,0,5,0" Padding="5,3">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="#FF4CAF50"/>
<Setter Property="Foreground" Value="White"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsContinuousReading}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="停止读取" Command="{Binding StopContinuousReadCommand}" Width="80" Padding="5,3"
Visibility="{Binding IsContinuousReading, Converter={StaticResource BoolToVisConverter}}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="#FFD32F2F"/>
<Setter Property="Foreground" Value="White"/>
</Style>
</Button.Style>
</Button>
</StackPanel>
</StackPanel>
</GroupBox>
<!-- 右侧:批量读取区 | Right: Batch read -->
<GroupBox Grid.Column="1" Header="批量读取 | Batch Read" Foreground="#FF333333" Margin="3,0,0,0"
BorderBrush="#FFBDBDBD" Background="#FFFFFFFF">
<DockPanel Margin="8">
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="起始地址:" VerticalAlignment="Center" Foreground="#FF333333" Margin="0,0,5,0"/>
<TextBox Grid.Column="1" Text="{Binding BatchAddress, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Grid.Column="2" Text="长度:" VerticalAlignment="Center" Foreground="#FF333333" Margin="5,0,5,0"/>
<TextBox Grid.Column="3" Text="{Binding BatchLength, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Margin="0,0,5,0"/>
<Button Grid.Column="4" Content="批量读取" Command="{Binding BatchReadCommand}" Width="80" Padding="5,3"/>
</Grid>
<!-- 十六进制查看器 | Hex viewer -->
<TextBox Margin="0,8,0,0" Text="{Binding HexViewerContent, Mode=OneWay}"
IsReadOnly="True" TextWrapping="NoWrap"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
FontFamily="Consolas" FontSize="12"
Background="#FFF0F0F0" Foreground="#FF1B5E20" BorderBrush="#FFBDBDBD"
AcceptsReturn="True"/>
</DockPanel>
</GroupBox>
</Grid>
<!-- 底部:日志输出区 | Bottom: Log output area -->
<GroupBox Grid.Row="2" Header="操作日志 | Operation Log" Foreground="#FF333333"
BorderBrush="#FFBDBDBD" Background="#FFFFFFFF">
<DockPanel Margin="5">
<Button DockPanel.Dock="Bottom" Content="清除日志" Command="{Binding ClearLogCommand}"
HorizontalAlignment="Right" Width="80" Margin="0,5,0,0" Padding="5,3"/>
<ListBox x:Name="LogListBox" ItemsSource="{Binding LogEntries}"
Background="#FFF9F9F9" BorderBrush="#FFBDBDBD"
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayText}" FontFamily="Consolas" FontSize="12"
TextWrapping="Wrap" Margin="2,1">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="#FF333333"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Level}" Value="WARN">
<Setter Property="Foreground" Value="#FFE68A00"/>
</DataTrigger>
<DataTrigger Binding="{Binding Level}" Value="ERROR">
<Setter Property="Foreground" Value="#FFD32F2F"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</DockPanel>
</GroupBox>
</Grid>
</Window>