| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- <Window xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:vm="using:YZWater.Core.ViewModels"
- xmlns:views="using:YZWater.Avalonia.Views"
- xmlns:conv="using:YZWater.Avalonia.Converters"
- xmlns:th="using:YZWater.Avalonia.Controls"
- x:Class="YZWater.Avalonia.Views.MainWindow"
- x:DataType="vm:MainViewModel"
- Title="{Binding Title}"
- Icon="/Assets/app-icon.png"
- WindowDecorations="None"
- Width="1280" Height="800"
- MinWidth="1024" MinHeight="700"
- WindowStartupLocation="CenterScreen"
- WindowState="Maximized"
- Background="{DynamicResource AppBgBrush}">
- <Window.DataContext>
- <vm:MainViewModel/>
- </Window.DataContext>
- <DockPanel>
- <!-- ═══ 自定义标题栏 ═══ -->
- <Border DockPanel.Dock="Top" Background="{DynamicResource NavBgBrush}" Height="32"
- PointerPressed="OnTitleBarPointerPressed" Cursor="Hand">
- <Grid ColumnDefinitions="Auto,*,Auto">
- <Image Source="/Assets/app-icon.png" Width="20" Height="20" Margin="8,0,4,0" VerticalAlignment="Center"/>
- <TextBlock Grid.Column="1" Text="{Binding Title}" FontSize="13" FontWeight="SemiBold"
- VerticalAlignment="Center" Foreground="{DynamicResource TextPrimaryBrush}"/>
- <StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center">
- <Button Content="─" Click="OnMinimizeClick" Classes="chrome-btn"/>
- <Button x:Name="MaximizeBtn" Content="☐" Click="OnMaximizeClick" Classes="chrome-btn"/>
- <Button Content="✕" Click="OnCloseClick" Classes="chrome-btn"
- Foreground="{DynamicResource DangerFgBrush}"/>
- </StackPanel>
- </Grid>
- </Border>
- <!-- ═══ 底部导航栏 ═══ -->
- <Border x:Name="NavBar" DockPanel.Dock="Bottom" Background="{DynamicResource NavBgBrush}"
- BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="4,0">
- <Grid ColumnDefinitions="*,Auto,Auto,Auto">
- <!-- 导航按钮 -->
- <StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Center" Spacing="0">
- <Button Command="{Binding ShowViewACommand}" Classes="nav-tab">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <Border Width="3" Height="14" CornerRadius="1"
- Background="{Binding IsTabAActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- <TextBlock Text="{Binding NavProcess}" FontFamily="Consolas, monospace" FontSize="11"
- FontWeight="{Binding IsTabAActive, Converter={x:Static conv:BoolConverters.ToFontWeight}}"
- Foreground="{Binding IsTabAActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- </StackPanel>
- </Button>
- <Border Background="{DynamicResource BorderBrush}" Width="1" Height="20" VerticalAlignment="Center"/>
- <Button Command="{Binding ShowViewBCommand}" Classes="nav-tab">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <Border Width="3" Height="14" CornerRadius="1"
- Background="{Binding IsTabBActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- <TextBlock Text="{Binding NavParams}" FontFamily="Consolas, monospace" FontSize="11"
- FontWeight="{Binding IsTabBActive, Converter={x:Static conv:BoolConverters.ToFontWeight}}"
- Foreground="{Binding IsTabBActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- </StackPanel>
- </Button>
- <Border Background="{DynamicResource BorderBrush}" Width="1" Height="20" VerticalAlignment="Center"/>
- <Button Command="{Binding ShowViewCCommand}" Classes="nav-tab">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <Border Width="3" Height="14" CornerRadius="1"
- Background="{Binding IsTabCActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- <TextBlock Text="{Binding NavFlow}" FontFamily="Consolas, monospace" FontSize="11"
- FontWeight="{Binding IsTabCActive, Converter={x:Static conv:BoolConverters.ToFontWeight}}"
- Foreground="{Binding IsTabCActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- </StackPanel>
- </Button>
- <Border Background="{DynamicResource BorderBrush}" Width="1" Height="20" VerticalAlignment="Center"/>
- <Button Command="{Binding ShowViewDCommand}" Classes="nav-tab">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <Border Width="3" Height="14" CornerRadius="1"
- Background="{Binding IsTabDActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- <TextBlock Text="{Binding NavAlarm}" FontFamily="Consolas, monospace" FontSize="11"
- FontWeight="{Binding IsTabDActive, Converter={x:Static conv:BoolConverters.ToFontWeight}}"
- Foreground="{Binding IsTabDActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- </StackPanel>
- </Button>
- <Border Background="{DynamicResource BorderBrush}" Width="1" Height="20" VerticalAlignment="Center"/>
- <Button Command="{Binding ShowViewECommand}" Classes="nav-tab">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <Border Width="3" Height="14" CornerRadius="1"
- Background="{Binding IsTabEActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- <TextBlock Text="{Binding NavAbout}" FontFamily="Consolas, monospace" FontSize="11"
- FontWeight="{Binding IsTabEActive, Converter={x:Static conv:BoolConverters.ToFontWeight}}"
- Foreground="{Binding IsTabEActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- </StackPanel>
- </Button>
- <Border Background="{DynamicResource BorderBrush}" Width="1" Height="20" VerticalAlignment="Center"/>
- <Button Command="{Binding ShowViewFCommand}" Classes="nav-tab">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <Border Width="3" Height="14" CornerRadius="1"
- Background="{Binding IsTabFActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- <TextBlock Text="{Binding NavAudit}" FontFamily="Consolas, monospace" FontSize="11"
- FontWeight="{Binding IsTabFActive, Converter={x:Static conv:BoolConverters.ToFontWeight}}"
- Foreground="{Binding IsTabFActive, Converter={x:Static conv:BoolConverters.ToBrush}}"/>
- </StackPanel>
- </Button>
- </StackPanel>
- <!-- 主题切换 -->
- <Button Grid.Column="1" Command="{Binding ToggleThemeCommand}" Classes="btn-toggle" Margin="8,0">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <TextBlock Text="{Binding ThemeIcon}" FontSize="14" VerticalAlignment="Center"/>
- <TextBlock Text="THEME" FontSize="10" VerticalAlignment="Center"
- Foreground="{DynamicResource TextSecondaryBrush}"/>
- </StackPanel>
- </Button>
- <!-- 语言切换 -->
- <Button Grid.Column="2" Command="{Binding ToggleLanguageCommand}" Classes="btn-toggle" Margin="0,0,8,0">
- <StackPanel Orientation="Horizontal" Spacing="6">
- <TextBlock Text="{Binding LangIcon}" FontSize="12" FontWeight="Bold" VerticalAlignment="Center"/>
- <TextBlock Text="LANG" FontSize="10" VerticalAlignment="Center"
- Foreground="{DynamicResource TextSecondaryBrush}"/>
- </StackPanel>
- </Button>
- <!-- 用户信息 + 模式指示 -->
- <StackPanel Grid.Column="3" Orientation="Horizontal" Spacing="8" Margin="8,0" VerticalAlignment="Center">
- <Border Background="{DynamicResource CardBgBrush}" CornerRadius="4" Padding="6,2">
- <TextBlock Text="{Binding HubStatusText}" FontSize="10" Foreground="{DynamicResource TextSecondaryBrush}"/>
- </Border>
- <!-- 用户信息区域(认证禁用时隐藏) -->
- <TextBlock Text="{Binding CurrentUserName}" FontSize="12" FontWeight="Bold" VerticalAlignment="Center"
- IsVisible="{Binding ShowUserInfo}"/>
- <Border Background="{DynamicResource PrimaryBrush}" CornerRadius="4" Padding="6,2"
- IsVisible="{Binding ShowUserInfo}">
- <TextBlock Text="{Binding CurrentUserRole}" FontSize="10" Foreground="White"/>
- </Border>
- <Button Command="{Binding ToggleUserDialogCommand}" IsVisible="{Binding CanManageUsers}"
- Content="{Binding UserManageText}" Padding="8,4" FontSize="11" Classes="btn-primary"/>
- <Button Command="{Binding LogoutCommand}" Content="{Binding LogoutText}" Padding="8,4" FontSize="11" Classes="btn-danger"
- IsVisible="{Binding ShowUserInfo}"/>
- </StackPanel>
- </Grid>
- </Border>
- <!-- ═══ PLC 通信中断横幅(ISA-101: 断线时全局可见警告)═══
- 独立占一行,不再浮在内容区顶部:压在页面标题栏上会把标题一起糊掉,
- 而断线恰恰是最需要看清"现在在哪个页面"的时候 -->
- <Border DockPanel.Dock="Top" IsVisible="{Binding !IsPlcConnected}"
- Background="#F39C12" Padding="12,6">
- <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="8">
- <TextBlock Text="⚠" FontSize="16" VerticalAlignment="Center" Foreground="#2C3E50"/>
- <TextBlock Text="{Binding PlcCommInterruptedText}"
- FontSize="13" FontWeight="Bold" VerticalAlignment="Center" Foreground="#2C3E50"/>
- </StackPanel>
- </Border>
- <!-- ═══ 主内容区域 ═══ -->
- <Panel>
- <!-- 视图内容(通过 CurrentView + DataTemplate 切换) -->
- <ContentControl Content="{Binding CurrentView}"/>
- <!-- ═══ 用户管理对话框 ═══ -->
- <Border IsVisible="{Binding ShowUserDialog}" ZIndex="100" Background="#CC000000">
- <Border Background="{DynamicResource CardBgBrush}" CornerRadius="12" Padding="24"
- MaxWidth="600" MaxHeight="500" VerticalAlignment="Center" HorizontalAlignment="Center"
- BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1">
- <DockPanel>
- <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Spacing="12" Margin="0,0,0,16">
- <TextBlock Text="{Binding UserManageText}" FontSize="18" FontWeight="Bold"/>
- <Button Content="{Binding CloseText}" Command="{Binding ToggleUserDialogCommand}" HorizontalAlignment="Right" Classes="btn-danger"/>
- </StackPanel>
- <!-- 创建用户 -->
- <Border DockPanel.Dock="Top" Background="{DynamicResource CardBgBrush}" CornerRadius="8" Padding="12" Margin="0,0,0,12">
- <StackPanel Spacing="8">
- <TextBlock Text="{Binding CreateNewUserText}" FontWeight="Bold" FontSize="14"/>
- <StackPanel Orientation="Horizontal" Spacing="8">
- <TextBox Text="{Binding NewUserName}" PlaceholderText="{Binding UserNameLabel}" Width="120"/>
- <TextBox Text="{Binding NewUserPassword}" PlaceholderText="{Binding PasswordLabel}" PasswordChar="●" Width="120"/>
- <TextBox Text="{Binding NewUserDisplayName}" PlaceholderText="{Binding DisplayNameLabel}" Width="120"/>
- <ComboBox SelectedIndex="{Binding NewUserRole}" Width="100">
- <ComboBoxItem Content="Viewer"/>
- <ComboBoxItem Content="Operator"/>
- <ComboBoxItem Content="Engineer"/>
- <ComboBoxItem Content="Admin"/>
- </ComboBox>
- <Button Content="{Binding CreateText}" Command="{Binding CreateUserCommand}" Classes="btn-success"/>
- </StackPanel>
- <TextBlock Text="{Binding UserManageMessage}" Foreground="Red" FontSize="12"/>
- </StackPanel>
- </Border>
- <!-- 用户列表 -->
- <DataGrid ItemsSource="{Binding UserList}" AutoGenerateColumns="False" IsReadOnly="True"
- GridLinesVisibility="Horizontal" CanUserResizeColumns="True">
- <DataGrid.Columns>
- <DataGridTextColumn Header="User" Binding="{Binding UserName}" Width="100"/>
- <DataGridTextColumn Header="Name" Binding="{Binding DisplayName}" Width="120"/>
- <DataGridTextColumn Header="Role" Binding="{Binding Role}" Width="80"/>
- <DataGridTextColumn Header="Status" Binding="{Binding IsActive}" Width="60"/>
- <DataGridTextColumn Header="Last Login" Binding="{Binding LastLoginTime, StringFormat='yyyy-MM-dd HH:mm'}" Width="140"/>
- <DataGridTemplateColumn Header="Action" Width="80">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <Button Content="{Binding IsActive, Converter={x:Static conv:BoolConverters.ToActiveText}}"
- Command="{Binding $parent[DataGrid].((vm:MainViewModel)DataContext).ToggleUserActiveCommand}"
- CommandParameter="{Binding}"
- Classes="btn-toggle" Padding="6,2" FontSize="11"/>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- </DataGrid.Columns>
- </DataGrid>
- </DockPanel>
- </Border>
- </Border>
- <!-- ═══ 退出确认对话框(破坏性操作需二次确认,防止误触 ✕ 停屏) ═══ -->
- <Border IsVisible="{Binding ShowExitDialog}" ZIndex="110" Background="#CC000000">
- <Border Background="{DynamicResource CardBgBrush}" CornerRadius="12" Padding="24"
- MaxWidth="420" VerticalAlignment="Center" HorizontalAlignment="Center"
- BorderBrush="{DynamicResource DangerFgBrush}" BorderThickness="1">
- <StackPanel Spacing="16">
- <StackPanel Orientation="Horizontal" Spacing="10">
- <TextBlock Text="⚠" FontSize="18" FontFamily="Segoe UI Symbol" VerticalAlignment="Center"
- Foreground="{DynamicResource DangerFgBrush}"/>
- <TextBlock Text="{Binding ExitConfirmTitleText}" FontSize="18" FontWeight="Bold"
- VerticalAlignment="Center"/>
- </StackPanel>
- <TextBlock Text="{Binding ExitConfirmMessageText}" FontSize="13" TextWrapping="Wrap"
- Foreground="{DynamicResource TextSecondaryBrush}"/>
- <StackPanel Orientation="Horizontal" Spacing="12" HorizontalAlignment="Right">
- <Button Content="{Binding CancelText}" Click="OnExitCancelClick"
- Classes="btn-toggle" MinWidth="88"/>
- <Button Content="{Binding ConfirmText}" Click="OnExitConfirmClick"
- Classes="btn-danger" MinWidth="88"/>
- </StackPanel>
- </StackPanel>
- </Border>
- </Border>
- </Panel>
- </DockPanel>
- </Window>
|