<Window x:Class="CrazyCoder.Views.IoControlWindow"
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"
Title="I/O 控制面板" Height="650" Width="900" WindowStartupLocation="CenterScreen">
<Window.Resources>
<Style x:Key="GroupBorder" TargetType="Border">
<Setter Property="BorderBrush" Value="#D0D0D0"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Margin" Value="0,0,0,6"/>
</Style>
<Style x:Key="SectionTitle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="4,3"/>
<Setter Property="FontSize" Value="13"/>
</Style>
<Style x:Key="ConfigLabel" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="4,2"/>
</Style>
<Style x:Key="ConfigComboBox" TargetType="ComboBox">
<Setter Property="Margin" Value="2"/>
<Setter Property="Height" Value="26"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
<Style x:Key="ConfigTextBox" TargetType="TextBox">
<Setter Property="Margin" Value="2"/>
<Setter Property="Height" Value="26"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="#D0D0D0"/>
</Style>
<Style x:Key="ActionButton" TargetType="Button">
<Setter Property="Height" Value="30"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Padding" Value="8,0"/>
</Style>
<Style x:Key="BigButton" TargetType="Button">
<Setter Property="Height" Value="40"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style x:Key="PortButton" TargetType="Button">
<Setter Property="Width" Value="80"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</Window.Resources>
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="280"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- ============ 左侧:配置面板 ============ -->
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto" Margin="0,0,4,0">
<StackPanel>
<!-- 串口配置 -->
<Border Style="{StaticResource GroupBorder}">
<StackPanel>
<TextBlock Text="串口配置" Style="{StaticResource SectionTitle}"/>
<Grid>
<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>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="端口" Style="{StaticResource ConfigLabel}"/>
<ComboBox Grid.Row="0" Grid.Column="1"
ItemsSource="{Binding PortNames}"
SelectedItem="{Binding PortName, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ConfigComboBox}"/>
<Button Grid.Row="0" Grid.Column="2" Content="刷新" Command="{Binding RefreshPortsCommand}"
Style="{StaticResource ActionButton}" Width="50"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="波特率" Style="{StaticResource ConfigLabel}"/>
<ComboBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding BaudRates}"
SelectedItem="{Binding BaudRate, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ConfigComboBox}"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="校验位" Style="{StaticResource ConfigLabel}"/>
<ComboBox Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding ParityOptions}"
SelectedIndex="{Binding ParityIndex, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ConfigComboBox}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="数据位" Style="{StaticResource ConfigLabel}"/>
<ComboBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding DataBitsOptions}"
SelectedItem="{Binding DataBits, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ConfigComboBox}"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="停止位" Style="{StaticResource ConfigLabel}"/>
<ComboBox Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding StopBitsOptions}"
SelectedIndex="{Binding StopBitsIndex, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ConfigComboBox}"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="站号" Style="{StaticResource ConfigLabel}"/>
<TextBox Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2"
Text="{Binding SlaveAddress, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ConfigTextBox}"/>
<Button Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="3"
Content="{Binding ConnectButtonText}"
Command="{Binding ToggleConnectCommand}"
Style="{StaticResource BigButton}" Foreground="White"/>
</Grid>
</StackPanel>
</Border>
<!-- 设备信息 -->
<Border Style="{StaticResource GroupBorder}">
<StackPanel>
<TextBlock Text="设备信息" Style="{StaticResource SectionTitle}"/>
<TextBlock Margin="4,2">
<Run FontWeight="Bold">型号:</Run>
<Run Text="{Binding ProductType, Mode=OneWay}"/>
</TextBlock>
<TextBlock Margin="4,2">
<Run FontWeight="Bold">版本:</Run>
<Run Text="{Binding FirmwareVersion, Mode=OneWay}"/>
</TextBlock>
<Button Content="读取设备信息" Command="{Binding ReadDeviceInfoCommand}"
Style="{StaticResource ActionButton}" Margin="4,2"/>
</StackPanel>
</Border>
<!-- 批量操作 -->
<Border Style="{StaticResource GroupBorder}">
<StackPanel>
<TextBlock Text="批量操作" Style="{StaticResource SectionTitle}"/>
<Button Content="读取输入" Command="{Binding ReadInputsCommand}"
Style="{StaticResource ActionButton}" Margin="4,2"/>
<Button Content="读取输出" Command="{Binding ReadOutputsCommand}"
Style="{StaticResource ActionButton}" Margin="4,2"/>
<Button Content="全部打开" Command="{Binding TurnOnAllCommand}"
Style="{StaticResource ActionButton}" Margin="4,2" Foreground="Green"/>
<Button Content="全部关闭" Command="{Binding TurnOffAllCommand}"
Style="{StaticResource ActionButton}" Margin="4,2" Foreground="Red"/>
<WrapPanel Margin="4,2">
<TextBlock Text="延迟(ms)" VerticalAlignment="Center" Margin="0,0,4,0"/>
<TextBox Text="{Binding Delay, UpdateSourceTrigger=PropertyChanged}" Width="60"
Style="{StaticResource ConfigTextBox}"/>
</WrapPanel>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
<!-- ============ 右侧:I/O 面板 + 日志 ============ -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 输出面板 -->
<Border Grid.Row="0" Style="{StaticResource GroupBorder}" Padding="4">
<StackPanel>
<TextBlock Text="输出端口(Output)" Style="{StaticResource SectionTitle}"/>
<WrapPanel>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 1" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output1, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="1"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="1"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 2" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output2, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="2"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="2"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 3" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output3, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="3"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="3"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 4" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output4, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="4"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="4"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 5" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output5, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="5"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="5"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 6" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output6, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="6"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="6"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 7" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output7, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="7"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="7"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
<Border BorderBrush="#4CAF50" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输出 8" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Output8, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开" Command="{Binding TurnOnCommand}" CommandParameter="8"
Width="30" Height="24" FontSize="11" Margin="1"/>
<Button Content="关" Command="{Binding TurnOffCommand}" CommandParameter="8"
Width="30" Height="24" FontSize="11" Margin="1"/>
</StackPanel>
</StackPanel>
</Border>
</WrapPanel>
</StackPanel>
</Border>
<!-- 输入面板 -->
<Border Grid.Row="1" Style="{StaticResource GroupBorder}" Padding="4">
<StackPanel>
<TextBlock Text="输入端口(Input)" Style="{StaticResource SectionTitle}"/>
<WrapPanel>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 1" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input1, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 2" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input2, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 3" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input3, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 4" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input4, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 5" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input5, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 6" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input6, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 7" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input7, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
<Border BorderBrush="#2196F3" BorderThickness="1" CornerRadius="4" Margin="4" Padding="4" Width="90">
<StackPanel>
<TextBlock Text="输入 8" HorizontalAlignment="Center" FontSize="11"/>
<Ellipse Width="20" Height="20" Fill="{Binding Input8, Converter={x:Null}}" HorizontalAlignment="Center" Margin="0,2"/>
</StackPanel>
</Border>
</WrapPanel>
</StackPanel>
</Border>
<!-- 日志 -->
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Style="{StaticResource GroupBorder}" Background="#FFF5E6">
<Grid>
<TextBlock Text="日志" Style="{StaticResource SectionTitle}" VerticalAlignment="Center"/>
<Button HorizontalAlignment="Right" Content="清空" Command="{Binding ClearLogCommand}"
Style="{StaticResource ActionButton}" Margin="0,2,4,2"/>
</Grid>
</Border>
<Border Grid.Row="1" Style="{StaticResource GroupBorder}">
<RichTextBox x:Name="txtLog" IsReadOnly="True" VerticalScrollBarVisibility="Auto"
FontFamily="Consolas" FontSize="12" Background="#1E1E1E" Foreground="#D4D4D4"/>
</Border>
</Grid>
</Grid>
</Grid>
</Window>
|