sirt factory connected

This commit is contained in:
Stoyan Zlatev 2025-01-28 14:39:42 +01:00
parent 1c2d2e70e9
commit db677b133c
26 changed files with 1333 additions and 618 deletions

View File

@ -822,6 +822,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TempPE", "TempPE", "{91CA98
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.GUI", "Ui\Common.GUI\Common.GUI.csproj", "{25A3BC33-563A-41EC-A1CB-4C5F520DDD53}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LaaPackages", "LaaPackages", "{2E31C385-4FFC-473E-9C00-D7DC48140704}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Utils\DateTimeServerShared\DateTimeServerShared.projitems*{4806d89a-fbfb-41bc-aaa7-2242444bf55a}*SharedItemsImports = 4

View File

@ -21,13 +21,14 @@
this.COMPort = name;
this.readAwaiter = new ManualResetEventSlim();
this.closeAwaiter = new ManualResetEventSlim();
var sp = new SysSerialPort(this.COMPort, baudRate, parity, dataBits, stopBits);
serialPorts.AddOrUpdate(
key: this.COMPort,
addValue: sp,
updateValueFactory: (_1, _2) => sp);
serialPorts.AddOrUpdate(this.COMPort, sp, (key, value) =>
{
value?.Close();
return sp;
});
}
public event Action Connected;
@ -36,9 +37,7 @@
public string COMPort { get; }
public bool IsOpen
=> serialPorts.TryGetValue(this.COMPort, out var sp)
&& sp.IsOpen;
public bool IsOpen => serialPorts.TryGetValue(this.COMPort, out var sp) && sp.IsOpen;
public void Close()
{
@ -47,7 +46,7 @@
try
{
sp.Close();
this.closeAwaiter.Wait(3000);
this.closeAwaiter.Wait(5000);
this.closeAwaiter.Reset();
sp.DataReceived -= this.SP_DataReceived;
@ -82,7 +81,7 @@
public IEnumerable<byte[]> ReadBytes()
{
var sp = this.GetOpenSP();
var sp = this.GetOpenedSP();
var size = sp.ReadBufferSize;
var buffer = new byte[size];
var length = 0;
@ -109,12 +108,14 @@
yield return buffer;
}
sp.Close();
}
}
public IEnumerable<string> ReadLines()
{
var sp = this.GetOpenSP();
var sp = this.GetOpenedSP();
var text = default(string);
using (sp)
@ -139,15 +140,17 @@
}
}
public void RemoveConnection()
public void Remove()
{
this.Close();
serialPorts.TryRemove(this.COMPort, out _);
if (serialPorts.TryRemove(this.COMPort, out var sp))
{
sp.Close();
}
}
public void Write(byte[] bytes)
{
var sp = this.GetOpenSP();
var sp = this.GetOpenedSP();
try
{
@ -161,7 +164,7 @@
public void Write(string text)
{
var sp = this.GetOpenSP();
var sp = this.GetOpenedSP();
try
{
@ -173,7 +176,7 @@
}
}
private SysSerialPort GetOpenSP()
private SysSerialPort GetOpenedSP()
{
if (!serialPorts.TryGetValue(this.COMPort, out var sp))
{
@ -182,6 +185,7 @@
if (!sp.IsOpen)
{
this.Close();
this.Open();
}

View File

@ -115,6 +115,8 @@
private void SerialPort_Connected()
{
this.IsConnected = true;
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
@ -130,6 +132,9 @@
private void SerialPort_Disconnected()
{
this.IsActivated = false;
this.IsConnected = false;
try
{
this.cancellationTokenSource?.Cancel();
@ -158,6 +163,8 @@
private void StartProcessingTasksAsync()
{
this.IsActivated = true;
this.processingTask = Task.Factory.StartNew(() =>
{
var manualResetEventSlim = new ManualResetEventSlim();

View File

@ -28,6 +28,10 @@
public int Frequency { get; protected set; }
public bool IsConnected { get; protected set; }
public bool IsActivated { get; protected set; }
public void Close()
{
this.serialPort.Close();
@ -84,6 +88,6 @@
}
public void RemoveConnection()
=> this.serialPort.RemoveConnection();
=> this.serialPort.Remove();
}
}

View File

@ -7,84 +7,95 @@
public class SIRTFactory
{
private readonly ConcurrentDictionary<string, SIRTBroadcaster> connections
private readonly ConcurrentDictionary<string, SIRTBroadcaster> broadcasters
= new ConcurrentDictionary<string, SIRTBroadcaster>();
public event Action<string> Logging;
public void CloseConnection(string portName)
{
if (this.connections.TryGetValue(portName, out var connection))
if (this.broadcasters.TryGetValue(portName, out var broadcaster))
{
connection.Close();
broadcaster.Logging -= this.NotifyMessage;
broadcaster.Close();
}
}
public void CloseConnections()
{
foreach (var connection in this.GetConnections())
foreach (var broadcaster in this.GetConnections())
{
connection.Close();
broadcaster.Logging -= this.NotifyMessage;
broadcaster.Close();
}
}
public void DequeueTasks(uint address)
{
foreach (var connection in this.GetConnections())
foreach (var broadcaster in this.GetConnections())
{
connection.DequeueTasks(address);
broadcaster.DequeueTasks(address);
}
}
public void OpenConnections()
{
foreach (var connection in this.GetConnections())
foreach (var broadcaster in this.GetConnections())
{
connection.Open();
broadcaster.Logging += this.NotifyMessage;
broadcaster.Open();
}
}
public void ConnectSIRT(string portName, Action<SIRTBroadcaster> callback)
{
if (!this.connections.TryGetValue(portName, out var broadcaster))
if (!this.broadcasters.TryGetValue(portName, out var broadcaster))
{
broadcaster = new SIRTBroadcaster(portName);
broadcaster.Logging += message => this.Logging?.Invoke(message);
broadcaster.Logging += this.NotifyMessage;
if (!this.connections.TryAdd(portName, broadcaster))
if (!this.broadcasters.TryAdd(portName, broadcaster))
{
broadcaster = null;
}
}
callback(broadcaster);
broadcaster?.Close();
broadcaster?.Open();
if (broadcaster?.IsActivated == false)
{
broadcaster?.Close();
broadcaster?.Open();
}
}
public void EnqueueTask(SIRTTask task)
{
foreach (var connection in this.GetConnections())
foreach (var broadcaster in this.GetConnections())
{
connection.EnqueueTask(task);
broadcaster.EnqueueTask(task);
}
}
public IEnumerable<string> GetPortNames()
=> this.connections.Keys.ToArray();
=> this.broadcasters.Keys.ToArray();
public void RemoveConnections()
{
foreach (var key in this.connections.Keys.ToArray())
foreach (var key in this.broadcasters.Keys.ToArray())
{
if (this.connections.TryRemove(key, out var broadcaster))
if (this.broadcasters.TryRemove(key, out var broadcaster))
{
broadcaster.Logging -= this.NotifyMessage;
broadcaster.RemoveConnection();
}
}
}
private void NotifyMessage(string message)
=> this.Logging?.Invoke(message);
private IEnumerable<SIRTBroadcaster> GetConnections()
=> this.connections.Values.ToArray();
=> this.broadcasters.Values.ToArray();
}
}

View File

@ -4,6 +4,6 @@
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="SIRT.ComPorts" value="com6com8" />
</appSettings>
</configuration>

View File

@ -79,11 +79,20 @@
<Compile Include="Controls\Eregister\SIRTFactory.xaml.cs">
<DependentUpon>SIRTFactory.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\GridLayout.xaml.cs">
<DependentUpon>GridLayout.xaml</DependentUpon>
</Compile>
<Compile Include="Models\Base\Appsettings.cs" />
<Compile Include="Models\Base\Arguments.cs" />
<Compile Include="Models\Data\EregisterDbContext.cs" />
<Compile Include="ViewModels\Base\GridItemVM[T].cs" />
<Compile Include="Models\Pages\Eregister\ManualProgrammingModel.cs" />
<Compile Include="Pages\ControlsPage.xaml.cs">
<DependentUpon>ControlsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\Eregister\AutomaticInitialize.xaml.cs">
<DependentUpon>AutomaticInitialize.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\Eregister\ManualProgrammingPage.xaml.cs">
<DependentUpon>ManualProgrammingPage.xaml</DependentUpon>
</Compile>
@ -91,10 +100,13 @@
<Compile Include="ViewModels\Base\ArgsVM[T].cs" />
<Compile Include="Models\Base\User32DllImports.cs" />
<Compile Include="Models\Base\WindowCommands.cs" />
<Compile Include="ViewModels\Eregister\AutomaticInitializeVM.cs" />
<Compile Include="ViewModels\Eregister\EregisterFeatureItemVM.cs" />
<Compile Include="ViewModels\Eregister\EregisterManualProgrammingVM.cs" />
<Compile Include="ViewModels\Eregister\FeatureDictionary.cs" />
<Compile Include="Models\Services.cs" />
<Compile Include="ViewModels\Eregister\SIRTFactoryVM.cs" />
<Compile Include="ViewModels\Eregister\SIRTVM.cs" />
<Page Include="Controls\Eregister\EregisterFeaturesItemsControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -103,6 +115,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\GridLayout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\MainLayout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -115,6 +131,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Pages\Eregister\AutomaticInitialize.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\Eregister\ManualProgrammingPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -156,6 +176,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Theme\Combobox.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Theme\Dropdowns.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -201,7 +225,6 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\Data\" />
<Folder Include="Models\Http\" />
<Folder Include="ViewModels\Controls\" />
<Folder Include="ViewModels\Pages\" />

View File

@ -1,14 +1,112 @@
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Common.GUI.Controls.Eregister.SIRTFactory" >
x:Class="Common.GUI.Controls.Eregister.SIRTFactory"
xmlns:ERVM="clr-namespace:Common.GUI.ViewModels.Eregister"
DataContext="{Binding SIRTFactoryVM, Source={StaticResource Services}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<ItemsControl Grid.Column="0" ItemsSource="{Binding Sirts}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type ERVM:SIRTVM}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" IsChecked="{Binding IsConnectedAndActive}" IsEnabled="False" Margin="13 5 0 5" />
<TextBlock Foreground="{DynamicResource onPrimary}" Grid.Column="1" Padding="10 5 0 5" Text="{Binding ComPort}" VerticalAlignment="Center" />
<TextBlock Foreground="{DynamicResource onPrimary}" Grid.Column="2" Padding="10 5 0 5" Text="{Binding Frequency}" VerticalAlignment="Center" />
<TextBlock Foreground="{DynamicResource onPrimary}" Grid.Column="3" Padding="10 5 0 5" Text="{Binding HexId}" VerticalAlignment="Center" />
<ToggleButton Background="{DynamicResource primary}"
Content="Connecting ..."
FontSize="11"
FontFamily="Verdana"
FontStyle="Italic"
Foreground="{DynamicResource onPrimary}"
Grid.Column="0"
Grid.ColumnSpan="100"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
IsChecked="{Binding IsConnecting}"
IsEnabled="False"
Opacity="0.9"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}"
BorderThickness="0"
CornerRadius="0">
<ContentPresenter Margin="15 5 0 5" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Grid.Column="1" Margin="0 0 10 5" Orientation="Vertical">
<Button Background="{DynamicResource primary}"
Command="{Binding RefreshConnections}"
HorizontalAlignment="Stretch"
Style="{StaticResource ButtonPrimary}"
Padding="20 5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Path Data="{StaticResource bi-reload-arrow}"
Fill="{DynamicResource md_theme_onPrimary}"
Stroke="{DynamicResource md_theme_onPrimary}"
Height="13"
HorizontalAlignment="Center"
Stretch="Uniform"
Width="13"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Margin="5 0 0 0" Text="Reconnect"/>
</Grid>
</Button>
<Button Background="{DynamicResource primary}"
Command="{Binding DisconnectConnections}"
HorizontalAlignment="Stretch"
Style="{StaticResource ButtonPrimary}"
Padding="20 5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Path Data="{StaticResource bi-octagon}"
Fill="{DynamicResource md_theme_onPrimary}"
Stroke="{DynamicResource md_theme_onPrimary}"
Height="13"
HorizontalAlignment="Center"
Stretch="Uniform"
Width="13"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Margin="5 0 0 0" Text="Disconnect"/>
</Grid>
</Button>
</StackPanel>
<ScrollViewer Grid.Column="1">
<ItemsControl />
</ScrollViewer>
</Grid>

View File

@ -0,0 +1,4 @@
<Grid x:Class="Common.GUI.Controls.GridLayout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
</Grid>

View File

@ -0,0 +1,45 @@
namespace Common.GUI.Controls
{
using System.Windows;
using System.Windows.Controls;
public partial class GridLayout : Grid
{
private static readonly DependencyProperty RowsCountProperty = DependencyProperty.Register(
name: nameof(RowsCount)
, propertyType: typeof(int)
, ownerType: typeof(GridLayout)
, typeMetadata: new FrameworkPropertyMetadata(
defaultValue: 0
, propertyChangedCallback: RowsCountChanged));
public GridLayout() => this.InitializeComponent();
public int RowsCount
{
get => this.GetValue(RowsCountProperty) is int rowsCount ? rowsCount : 0;
set => this.SetValue(RowsCountProperty, value);
}
private static void RowsCountChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
if (dependencyObject is GridLayout gridLayout)
{
if (args.NewValue is int newRowsCount)
{
var rowDefinitions = gridLayout.RowDefinitions;
while (rowDefinitions.Count > newRowsCount)
{
rowDefinitions.RemoveAt(rowDefinitions.Count - 1);
}
while (rowDefinitions.Count < newRowsCount)
{
rowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
}
}
}
}
}
}

View File

@ -4,554 +4,6 @@
Background="{DynamicResource primary}"
BorderThickness="0">
<Menu.Resources>
<MenuScrollingVisibilityConverter x:Key="MenuScrollingVisibilityConverter"/>
<Geometry x:Key="DownArrow">M 0,0 L 3.5,4 L 7,0 Z</Geometry>
<Geometry x:Key="UpArrow">M 0,4 L 3.5,0 L 7,4 Z</Geometry>
<Geometry x:Key="RightArrow">M 0,0 L 4,3.5 L 0,7 Z</Geometry>
<Geometry x:Key="Checkmark">F1 M 10.0,1.2 L 4.7,9.1 L 4.5,9.1 L 0,5.2 L 1.3,3.5 L 4.3,6.1L 8.3,0 L 10.0,1.2 Z</Geometry>
<Style x:Key="MenuScrollButton" BasedOn="{x:Null}" TargetType="{x:Type RepeatButton}">
<Setter Property="ClickMode" Value="Hover"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="templateRoot"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="Center"
Margin="6"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}"
TargetType="{x:Type ScrollViewer}"
BasedOn="{x:Null}">
<Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="1">
<ScrollContentPresenter CanContentScroll="{TemplateBinding CanContentScroll}"
Margin="{TemplateBinding Padding}"/>
</Border>
<RepeatButton Command="{x:Static ScrollBar.LineUpCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}"
Grid.Column="0"
Focusable="false"
Grid.Row="0"
Style="{StaticResource MenuScrollButton}">
<RepeatButton.Visibility>
<MultiBinding ConverterParameter="0"
Converter="{StaticResource MenuScrollingVisibilityConverter}"
FallbackValue="Visibility.Collapsed">
<Binding Path="ComputedVerticalScrollBarVisibility"
RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="VerticalOffset" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ExtentHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ViewportHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
</MultiBinding>
</RepeatButton.Visibility>
<Path Data="{StaticResource UpArrow}"
Fill="{DynamicResource onPrimary}"/>
</RepeatButton>
<RepeatButton Command="{x:Static ScrollBar.LineDownCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}"
Grid.Column="0"
Focusable="false"
Grid.Row="2"
Style="{StaticResource MenuScrollButton}">
<RepeatButton.Visibility>
<MultiBinding ConverterParameter="100"
Converter="{StaticResource MenuScrollingVisibilityConverter}"
FallbackValue="Visibility.Collapsed">
<Binding Path="ComputedVerticalScrollBarVisibility"
RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="VerticalOffset" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ExtentHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ViewportHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
</MultiBinding>
</RepeatButton.Visibility>
<Path Data="{StaticResource DownArrow}"
Fill="{DynamicResource onPrimary}"/>
</RepeatButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="3"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Path x:Name="GlyphPanel"
Data="{StaticResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{DynamicResource onPrimary}"
Margin="3"
VerticalAlignment="Center"
Visibility="Collapsed"/>
<ContentPresenter ContentSource="Header"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
<Setter Property="Padding"
TargetName="templateRoot"
Value="10 0"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="GlyphPanel"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="10 0"
SnapsToDevicePixels="true">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="3 10 3 10"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Path x:Name="GlyphPanel"
Data="{StaticResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{TemplateBinding Foreground}"
Margin="3"
VerticalAlignment="Center"
Visibility="Collapsed"/>
<ContentPresenter ContentSource="Header"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
Focusable="false"
IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Placement="Bottom"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
PlacementTarget="{Binding ElementName=templateRoot}">
<Border x:Name="SubMenuBorder"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
Padding="0">
<ScrollViewer x:Name="SubMenuScrollViewer"
Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer
, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect"
Fill="{Binding Background, ElementName=SubMenuBorder}"
Height="{Binding ActualHeight, ElementName=SubMenuBorder}"
Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="{DynamicResource md_theme_secondaryContainer}"
HorizontalAlignment="Left"
Margin="29,2,0,2"
Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="true"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
<Setter Property="Margin"
TargetName="templateRoot"
Value="10 0"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="GlyphPanel"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="false">
<Setter Property="Canvas.Top"
TargetName="OpaqueRect"
Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left"
TargetName="OpaqueRect"
Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="10 4"
SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="0"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Border x:Name="GlyphPanel"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
ClipToBounds="False"
HorizontalAlignment="Center"
Height="22"
Margin="-1,0,0,0"
VerticalAlignment="Center"
Visibility="Hidden"
Width="22">
<Path x:Name="Glyph"
Data="{StaticResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{DynamicResource onPrimary}"
Height="11"
Width="10"/>
</Border>
<ContentPresenter x:Name="menuHeaderContainer"
ContentSource="Header"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText"
Grid.Column="4"
Margin="{TemplateBinding Padding}"
Opacity="0.7"
Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="Glyph"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="3"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Border x:Name="GlyphPanel"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
Height="22"
Margin="-1,0,0,0"
VerticalAlignment="Center"
Visibility="Hidden"
Width="22">
<Path x:Name="Glyph"
Data="{DynamicResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{DynamicResource onPrimary}"
Height="11"
Width="9"/>
</Border>
<ContentPresenter ContentSource="Header"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="4"
Margin="{TemplateBinding Padding}"
Opacity="0.7"
Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
<Path x:Name="RightArrow"
Grid.Column="5"
Data="{StaticResource RightArrow}"
Fill="{DynamicResource onPrimary}"
HorizontalAlignment="Left"
Margin="10,0,0,0"
VerticalAlignment="Center"/>
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
Focusable="false"
HorizontalOffset="-2"
IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Placement="Right"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
VerticalOffset="-3">
<Border x:Name="SubMenuBorder"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer"
Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer
, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect"
Fill="{Binding Background, ElementName=SubMenuBorder}"
Height="{Binding ActualHeight, ElementName=SubMenuBorder}"
Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
HorizontalAlignment="Left"
Margin="29,2,0,2"
Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="true"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot" Value="Transparent"/>
<Setter Property="BorderBrush"
TargetName="templateRoot" Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="Glyph"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="RightArrow"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="false">
<Setter Property="Canvas.Top"
TargetName="OpaqueRect"
Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left"
TargetName="OpaqueRect"
Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Background" Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush" Value="{DynamicResource primary}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="Template"
Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey
, TypeInTargetAssembly={x:Type MenuItem}}}"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Background" Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush" Value="{DynamicResource primary}"/>
<Setter Property="Foreground" Value="{DynamicResource onPrimary}"/>
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
<Setter Property="Padding" Value="0 10"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Background" Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush" Value="{DynamicResource primary}"/>
<Setter Property="Foreground" Value="{DynamicResource onPrimary}"/>
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
<Setter Property="Padding" Value="0 10"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
</Trigger>
</Style.Triggers>
</Style>
</Menu.Resources>
<MenuItem Style="{DynamicResource MenuItemStyle}">
<MenuItem.Icon>
@ -594,5 +46,9 @@
CommandParameter="Pages/Eregister/ManualProgrammingPage.xaml"
Header="Manual Programming"
Style="{StaticResource MenuItemStyle}" />
<MenuItem Click="MenuItem_Click_Navigate"
CommandParameter="Pages/Eregister/AutomaticInitialize.xaml"
Header="Auto Initialize"
Style="{StaticResource MenuItemStyle}" />
</MenuItem>
</Menu>

View File

@ -0,0 +1,31 @@
namespace Common.GUI.Models.Base
{
using System;
using System.Configuration;
using System.Linq;
public class Appsettings
{
private static readonly string dll = typeof(App).Assembly.Location;
public static string GetOrCreateSetting(string settingKey)
{
if (string.IsNullOrWhiteSpace(settingKey))
{
return default(string);
}
var configuration = ConfigurationManager.OpenExeConfiguration(dll);
var settings = configuration.AppSettings.Settings;
if (!settings.AllKeys.Any(x => x.Equals(settingKey, StringComparison.OrdinalIgnoreCase)))
{
settings.Add(settingKey, string.Empty);
configuration.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
return settings[settingKey].Value;
}
}
}

View File

@ -6,8 +6,6 @@
{
private object[] values = Array.Empty<object>();
public object[] Values => this.values;
internal void Reset()
=> Array.Resize(ref this.values, 0);
@ -25,5 +23,15 @@
Array.Resize(ref this.values, argsLength);
Array.Copy(arguments, 0, this.values, 0, argsLength);
}
internal T Get<T>(int i, T @default = default(T))
{
if ((this.values?.Length ?? 0) > i && this.values[i] is T value)
{
return value;
}
return @default;
}
}
}

View File

@ -0,0 +1,7 @@
namespace Common.GUI.Models.Data
{
public class EregisterDbContext
{
}
}

View File

@ -3,6 +3,7 @@
using Common.GUI.Models.Base;
using Common.GUI.ViewModels.Eregister;
using Common.Hardware.SIRT;
using Common.Hardware.WaterMeter.eRegister;
using Microsoft.Extensions.DependencyInjection;
@ -16,6 +17,10 @@
public EregisterManualProgrammingVM EregisterManualProgrammingVM => serviceProvider.GetService<EregisterManualProgrammingVM>();
public AutomaticInitializeVM AutomaticInitializeVM => serviceProvider.GetService<AutomaticInitializeVM>();
public SIRTFactoryVM SIRTFactoryVM => serviceProvider.GetService<SIRTFactoryVM>();
private void App_Exit(object sender, ExitEventArgs args)
{
App.Current.Exit -= this.App_Exit;
@ -24,10 +29,13 @@
}
private static ServiceProvider ConfigureServices()
=> new ServiceCollection()
=> new ServiceCollection()
.AddSingleton<Arguments>()
.AddSingleton<EregisterManualProgrammingVM>()
.AddSingleton<AutomaticInitializeVM>()
.AddSingleton<SIRTFactory>()
.AddSingleton<SIRTFactoryVM>()
.AddSingleton<EregisterFactory>()
.BuildServiceProvider();
public static T GetService<T>()

View File

@ -0,0 +1,28 @@
<Page x:Class="Common.GUI.Pages.Eregister.AutomaticInitialize"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Common.GUI.Controls"
xmlns:ERControls="clr-namespace:Common.GUI.Controls.Eregister" >
<Controls:MainLayout>
<Grid DataContext="{Binding AutomaticInitializeVM, Source={StaticResource Services}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ERControls:SIRTFactory Background="{DynamicResource primary}"
Grid.Row="0" />
<GridSplitter Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0 1"
Grid.Row="1"
ResizeDirection="Rows"
HorizontalAlignment="Stretch"
ResizeBehavior="PreviousAndNext"
Height="2"/>
<ScrollViewer Grid.Row="2">
</ScrollViewer>
</Grid>
</Controls:MainLayout>
</Page>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Common.GUI.Pages.Eregister
{
/// <summary>
/// Interaction logic for AutomaticInitialize.xaml
/// </summary>
public partial class AutomaticInitialize : Page
{
public AutomaticInitialize()
{
InitializeComponent();
}
}
}

View File

@ -2,9 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Common.GUI.Controls"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2"
FontFamily="Verdana">
<Page.Resources>
</Page.Resources>
<Controls:MainLayout>
<Grid>
<Grid.ColumnDefinitions>

View File

@ -0,0 +1,161 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Border x:Name="Border"
Background="{DynamicResource md_theme_surfaceContainer}"
BorderBrush="{DynamicResource md_theme_surfaceContainer}"
BorderThickness="0"
CornerRadius="3"
Grid.ColumnSpan="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Path x:Name="Arrow"
Grid.Column="1"
Fill="{DynamicResource md_theme_onSurfaceContainer}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{StaticResource bi-chevron-down}" />
</Grid>
</Border>
<!--<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="#808080" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="#EEEEEE" />
<Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
<Setter Property="Foreground" Value="#888888"/>
<Setter TargetName="Arrow" Property="Fill" Value="#888888" />
</Trigger>
</ControlTemplate.Triggers>-->
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost"
Focusable="False"
Background="{DynamicResource md_theme_surfaceContainer}"
BorderBrush="{DynamicResource md_theme_surfaceContainer}"
BorderThickness="0" />
</ControlTemplate>
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,3,23,3"
Focusable="True"
Background="#FF3F3F3F"
Foreground="Green"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
Background="#FF3F3F3F"
BorderThickness="1"
BorderBrush="#888888"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="#FF4F4F4F"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@ -24,6 +24,10 @@
FillRule="evenodd"
Figures="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"/>
<PathGeometry x:Key="bi-chevron-down"
FillRule="evenodd"
Figures="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" />
<GeometryGroup x:Key="bi_home_fill">
<PathGeometry Figures="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L8 2.207l6.646 6.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293z"/>
<PathGeometry Figures="m8 3.293 6 6V13.5a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 13.5V9.293z"/>
@ -38,4 +42,14 @@
<PathGeometry Figures="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.73 1.73 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.73 1.73 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.73 1.73 0 0 0 1.097-1.097zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.16 1.16 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.16 1.16 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732z"/>
</GeometryGroup>
<GeometryGroup x:Key="bi-reload-arrow">
<PathGeometry FillRule="evenodd" Figures="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2z"/>
<PathGeometry Figures="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466"/>
</GeometryGroup>
<GeometryGroup x:Key="bi-octagon">
<PathGeometry Figures="M4.54.146A.5.5 0 0 1 4.893 0h6.214a.5.5 0 0 1 .353.146l4.394 4.394a.5.5 0 0 1 .146.353v6.214a.5.5 0 0 1-.146.353l-4.394 4.394a.5.5 0 0 1-.353.146H4.893a.5.5 0 0 1-.353-.146L.146 11.46A.5.5 0 0 1 0 11.107V4.893a.5.5 0 0 1 .146-.353zM5.1 1 1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1z"/>
<PathGeometry Figures="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>
</GeometryGroup>
</ResourceDictionary>

View File

@ -315,9 +315,9 @@
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
@ -358,13 +358,13 @@
<Setter Property="Background" Value="{DynamicResource md_theme_background}"/>
<Setter Property="FontSize" Value="13"/>
</Style>
<Style x:Key="Lable" TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="{DynamicResource md_theme_onBackground}"/>
<Setter Property="Background" Value="{DynamicResource md_theme_background}"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style x:Key="Button" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{DynamicResource md_theme_surfaceContainerHighest}"/>
@ -382,18 +382,18 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3"
SnapsToDevicePixels="True">
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3"
SnapsToDevicePixels="True">
<ContentPresenter x:Name="contentPresenter"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="True">
@ -876,4 +876,554 @@
</Trigger>
</Style.Triggers>
</Style>
<MenuScrollingVisibilityConverter x:Key="MenuScrollingVisibilityConverter"/>
<Geometry x:Key="DownArrow">M 0,0 L 3.5,4 L 7,0 Z</Geometry>
<Geometry x:Key="UpArrow">M 0,4 L 3.5,0 L 7,4 Z</Geometry>
<Geometry x:Key="RightArrow">M 0,0 L 4,3.5 L 0,7 Z</Geometry>
<Geometry x:Key="Checkmark">F1 M 10.0,1.2 L 4.7,9.1 L 4.5,9.1 L 0,5.2 L 1.3,3.5 L 4.3,6.1L 8.3,0 L 10.0,1.2 Z</Geometry>
<Style x:Key="MenuScrollButton" BasedOn="{x:Null}" TargetType="{x:Type RepeatButton}">
<Setter Property="ClickMode" Value="Hover"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="templateRoot"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="Center"
Margin="6"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}"
TargetType="{x:Type ScrollViewer}"
BasedOn="{x:Null}">
<Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="1">
<ScrollContentPresenter CanContentScroll="{TemplateBinding CanContentScroll}"
Margin="{TemplateBinding Padding}"/>
</Border>
<RepeatButton Command="{x:Static ScrollBar.LineUpCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}"
Grid.Column="0"
Focusable="false"
Grid.Row="0"
Style="{StaticResource MenuScrollButton}">
<RepeatButton.Visibility>
<MultiBinding ConverterParameter="0"
Converter="{StaticResource MenuScrollingVisibilityConverter}"
FallbackValue="Visibility.Collapsed">
<Binding Path="ComputedVerticalScrollBarVisibility"
RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="VerticalOffset" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ExtentHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ViewportHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
</MultiBinding>
</RepeatButton.Visibility>
<Path Data="{StaticResource UpArrow}"
Fill="{DynamicResource onPrimary}"/>
</RepeatButton>
<RepeatButton Command="{x:Static ScrollBar.LineDownCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}}"
Grid.Column="0"
Focusable="false"
Grid.Row="2"
Style="{StaticResource MenuScrollButton}">
<RepeatButton.Visibility>
<MultiBinding ConverterParameter="100"
Converter="{StaticResource MenuScrollingVisibilityConverter}"
FallbackValue="Visibility.Collapsed">
<Binding Path="ComputedVerticalScrollBarVisibility"
RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="VerticalOffset" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ExtentHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
<Binding Path="ViewportHeight" RelativeSource="{RelativeSource Mode=TemplatedParent}"/>
</MultiBinding>
</RepeatButton.Visibility>
<Path Data="{StaticResource DownArrow}"
Fill="{DynamicResource onPrimary}"/>
</RepeatButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="3"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Path x:Name="GlyphPanel"
Data="{StaticResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{DynamicResource onPrimary}"
Margin="3"
VerticalAlignment="Center"
Visibility="Collapsed"/>
<ContentPresenter ContentSource="Header"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
<Setter Property="Padding"
TargetName="templateRoot"
Value="10 0"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="GlyphPanel"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="10 0"
SnapsToDevicePixels="true">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="3 10 3 10"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Path x:Name="GlyphPanel"
Data="{StaticResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{TemplateBinding Foreground}"
Margin="3"
VerticalAlignment="Center"
Visibility="Collapsed"/>
<ContentPresenter ContentSource="Header"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
Focusable="false"
IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Placement="Bottom"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
PlacementTarget="{Binding ElementName=templateRoot}">
<Border x:Name="SubMenuBorder"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
Padding="0">
<ScrollViewer x:Name="SubMenuScrollViewer"
Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer
, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect"
Fill="{Binding Background, ElementName=SubMenuBorder}"
Height="{Binding ActualHeight, ElementName=SubMenuBorder}"
Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="{DynamicResource md_theme_secondaryContainer}"
HorizontalAlignment="Left"
Margin="29,2,0,2"
Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="true"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
<Setter Property="Margin"
TargetName="templateRoot"
Value="10 0"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="GlyphPanel"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="false">
<Setter Property="Canvas.Top"
TargetName="OpaqueRect"
Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left"
TargetName="OpaqueRect"
Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="10 4"
SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="0"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Border x:Name="GlyphPanel"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
ClipToBounds="False"
HorizontalAlignment="Center"
Height="22"
Margin="-1,0,0,0"
VerticalAlignment="Center"
Visibility="Hidden"
Width="22">
<Path x:Name="Glyph"
Data="{StaticResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{DynamicResource onPrimary}"
Height="11"
Width="10"/>
</Border>
<ContentPresenter x:Name="menuHeaderContainer"
ContentSource="Header"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText"
Grid.Column="4"
Margin="{TemplateBinding Padding}"
Opacity="0.7"
Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="Glyph"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush"
TargetName="templateRoot"
Value="{DynamicResource primary}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentSource="Icon"
HorizontalAlignment="Center"
Height="16"
Margin="3"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
Width="16"/>
<Border x:Name="GlyphPanel"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
Height="22"
Margin="-1,0,0,0"
VerticalAlignment="Center"
Visibility="Hidden"
Width="22">
<Path x:Name="Glyph"
Data="{DynamicResource Checkmark}"
FlowDirection="LeftToRight"
Fill="{DynamicResource onPrimary}"
Height="11"
Width="9"/>
</Border>
<ContentPresenter ContentSource="Header"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="4"
Margin="{TemplateBinding Padding}"
Opacity="0.7"
Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
<Path x:Name="RightArrow"
Grid.Column="5"
Data="{StaticResource RightArrow}"
Fill="{DynamicResource onPrimary}"
HorizontalAlignment="Left"
Margin="10,0,0,0"
VerticalAlignment="Center"/>
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
Focusable="false"
HorizontalOffset="-2"
IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Placement="Right"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
VerticalOffset="-3">
<Border x:Name="SubMenuBorder"
Background="{DynamicResource primary}"
BorderBrush="{DynamicResource primary}"
BorderThickness="0"
Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer"
Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer
, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect"
Fill="{Binding Background, ElementName=SubMenuBorder}"
Height="{Binding ActualHeight, ElementName=SubMenuBorder}"
Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
HorizontalAlignment="Left"
Margin="29,2,0,2"
Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="true"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background"
TargetName="templateRoot" Value="Transparent"/>
<Setter Property="BorderBrush"
TargetName="templateRoot" Value="{DynamicResource md_theme_primary}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground"
TargetName="templateRoot"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="Glyph"
Value="{DynamicResource md_theme_secondaryContainer}"/>
<Setter Property="Fill"
TargetName="RightArrow"
Value="{DynamicResource md_theme_secondaryContainer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="false">
<Setter Property="Canvas.Top"
TargetName="OpaqueRect"
Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left"
TargetName="OpaqueRect"
Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Background" Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush" Value="{DynamicResource primary}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="Template"
Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey
, TypeInTargetAssembly={x:Type MenuItem}}}"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Background" Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush" Value="{DynamicResource primary}"/>
<Setter Property="Foreground" Value="{DynamicResource onPrimary}"/>
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
<Setter Property="Padding" Value="0 10"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Background" Value="{DynamicResource primary}"/>
<Setter Property="BorderBrush" Value="{DynamicResource primary}"/>
<Setter Property="Foreground" Value="{DynamicResource onPrimary}"/>
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
<Setter Property="Padding" Value="0 10"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

View File

@ -0,0 +1,33 @@
namespace Common.GUI.ViewModels.Base
{
public class GridItemVM<T> : VM<T> where T : GridItemVM<T>
{
private int column;
public int Column
{
get => this.column;
set => this.SetValue(x => x.column = value);
}
private int columnSpan = 1;
public int ColumnSpan
{
get => this.columnSpan;
set => this.SetValue(x => x.columnSpan = value);
}
private int row;
public int Row
{
get => this.row;
set => this.SetValue(x => x.row = value);
}
private int rowSpan = 1;
public int RowSpan
{
get => this.rowSpan;
set => this.SetValue(x => x.rowSpan = value);
}
}
}

View File

@ -1,7 +1,5 @@
namespace Common.GUI.ViewModels.Base
{
using Common.GUI.Models.Base;
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
@ -15,6 +13,12 @@
}
protected void InvokeOnMainThread(Action action)
=> App.Current.Dispatcher.Invoke(action);
protected void InvokeOnMainThreadAsync(Action action)
=> App.Current.Dispatcher.InvokeAsync(action);
protected void NotifyPropertyChanged([CallerMemberName] string member = "")
=> this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(member));

View File

@ -0,0 +1,30 @@
namespace Common.GUI.ViewModels.Eregister
{
using Common.GUI.Models.Base;
using Common.GUI.ViewModels.Base;
using Common.Hardware.WaterMeter.eRegister;
public class AutomaticInitializeVM : ArgsVM<AutomaticInitializeVM>
{
private readonly EregisterFactory eregisterFactory;
private readonly int sharedId;
public AutomaticInitializeVM(Arguments arguments, EregisterFactory eregisterFactory) : base(arguments)
{
this.eregisterFactory = eregisterFactory;
this.sharedId = arguments.Get(0, 1);
this.InitializeVM();
}
public override void Dispose()
{
}
private void InitializeVM()
{
}
}
}

View File

@ -0,0 +1,79 @@
namespace Common.GUI.ViewModels.Eregister
{
using Common.GUI.Models.Base;
using Common.GUI.ViewModels.Base;
using Common.Hardware.SIRT;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Input;
public class SIRTFactoryVM : VM<SIRTFactoryVM>
{
private readonly SIRTFactory sirtFactory;
public SIRTFactoryVM(SIRTFactory sirtFactory)
{
this.sirtFactory = sirtFactory;
this.RefreshConnections = new Command(this.RefreshConnectionsHandler);
this.DisconnectConnections = new Command(this.DisconnectConnectionsHandler);
this.InitializeVM();
}
public ICommand RefreshConnections { get; }
public ICommand DisconnectConnections { get; }
public ObservableCollection<SIRTVM> Sirts { get; }
= new ObservableCollection<SIRTVM>();
public override void Dispose()
{
this.Sirts.Clear();
this.sirtFactory.RemoveConnections();
}
private void InitializeVM()
=> Task.Factory.StartNew(this.InitializeSirtBroadcaster);
private void InitializeSirtBroadcaster()
{
var comportsList = Appsettings.GetOrCreateSetting("SIRT.ComPorts");
var comportsMatches = Regex.Matches($"{comportsList}", "[Cc][Oo][Mm][0-9]+");
foreach (Match match in comportsMatches)
{
if (match.Success)
{
var comport = match.Value.ToUpper();
this.sirtFactory.ConnectSIRT(comport, broadcaster =>
{
this.InvokeOnMainThreadAsync(() =>
{
this.Sirts.Add(new SIRTVM(broadcaster, this.Sirts.Count));
});
});
}
}
}
private void DisconnectConnectionsHandler()
{
this.Sirts.Clear();
Task.Factory.StartNew(this.sirtFactory.RemoveConnections);
}
private void RefreshConnectionsHandler()
{
this.Sirts.Clear();
Task.Factory
.StartNew(this.sirtFactory.RemoveConnections)
.ContinueWith(_ => this.InitializeSirtBroadcaster());
}
}
}

View File

@ -0,0 +1,81 @@
namespace Common.GUI.ViewModels.Eregister
{
using Common.GUI.ViewModels.Base;
using Common.Hardware.SIRT;
public class SIRTVM : GridItemVM<SIRTVM>
{
private SIRTBroadcaster broadcaster;
public SIRTVM(SIRTBroadcaster broadcaster, int row)
{
this.Row = row;
this.IsConnecting = true;
this.IsConnectedAndActive = false;
this.broadcaster = broadcaster;
this.broadcaster.Activated += this.Broadcaster_Activated;
this.broadcaster.Connected += this.Broadcaster_Connected;
this.broadcaster.Disconnected += this.Broadcaster_Disconnected;
}
private bool? isConnecting;
public bool? IsConnecting
{
get => this.isConnecting;
set => this.SetValue(x => x.isConnecting = value);
}
private bool? isConnectedAndActive;
public bool? IsConnectedAndActive
{
get => this.isConnectedAndActive;
set => this.SetValue(x => x.isConnectedAndActive = value);
}
private string hexId;
public string HexId
{
get => this.hexId;
set => this.SetValue(x => x.hexId = value);
}
private string comPort;
public string ComPort
{
get => this.comPort;
set => this.SetValue(x => x.comPort = value);
}
private int? frequency;
public int? Frequency
{
get => this.frequency;
set => this.SetValue(x => x.frequency = value);
}
private void Broadcaster_Activated()
{
this.IsConnectedAndActive = true;
this.HexId = this.broadcaster.HexId;
this.ComPort = this.broadcaster.COMPort;
this.Frequency = this.broadcaster.Frequency;
}
private void Broadcaster_Connected()
{
this.IsConnecting = false;
this.IsConnectedAndActive = null;
this.HexId = default(string);
this.ComPort = this.broadcaster.COMPort;
this.Frequency = default(int?);
}
private void Broadcaster_Disconnected()
{
this.IsConnectedAndActive = false;
this.HexId = default(string);
this.ComPort = default(string);
this.Frequency = default(int?);
}
}
}