This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Media;
using DTS.Common.Base;
using DTS.Common.Interface;
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Main class to bind to treeview
/// </summary>
public class TreeViewChannels : IBaseModel
{
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private ObservableCollection<TestGroup> _groups = new ObservableCollection<TestGroup>();
public ObservableCollection<TestGroup> Groups { get => _groups; set { _groups = value; _groupsCount = _groups.Count; OnPropertyChanged("Groups"); } }
private int _groupsCount = 0;
public int GroupsCount { get => _groupsCount; set { _groupsCount = value; OnPropertyChanged("GroupsCount"); } }
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
public bool IsSaved { get; }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _isSelected = false;
public bool IsSelected { get => _isSelected; set { _isSelected = value; OnPropertyChanged("IsSelected"); } }
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion PropertyChanged
}
/// <summary>
/// Child class for TreeViewChannels
/// </summary>
public class TestGroup : INotifyPropertyChanged
{
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
private string _dtsFile = string.Empty;
public string DTSFile { get => _dtsFile; set { _dtsFile = value; OnPropertyChanged("DTSFile"); } }
private IBaseViewModel _parent;
/// <summary>
/// Parent ViewModel
/// </summary>
public IBaseViewModel Parent { get => _parent; set { _parent = value; OnPropertyChanged("Parent"); } }
private bool _isLocked = false;
/// <summary>
/// Locked Graph - call parent function to lock graph's channels
/// </summary>
public bool IsLocked
{
get => _isLocked;
set
{
_isLocked = value;
((IGraphMainViewModel)Parent).AddLockedGroupChannels(TestName, Name, Channels.ToList(), _isLocked);
OnPropertyChanged("IsLocked");
}
}
private bool _isGraph = false;
public bool IsGraph { get => _isGraph; set { _isGraph = value; OnPropertyChanged("IsGraph"); } }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _canLock = true;
public bool CanLock
{
get => _canLock;
set
{
_canLock = value;
OnPropertyChanged("CanLock");
}
}
private bool _isSelected = false;
/// <summary>
/// Selected Graph - call parent function to select graph's channels
/// </summary>
public bool IsSelected
{
get => _isSelected;
set
{
if (!CanLock && value)
{
return; //ignore, don't select
}
if (Name.StartsWith("Test Channels") || Name.StartsWith("Calculated Channels")) return;
var prevValue = _isSelected;
_isSelected = value;
if (IsSelected && IsSelected != prevValue) ((IGraphMainViewModel)Parent).AddSelectedGroupChannels(Name, Channels.ToList());
OnPropertyChanged("IsSelected");
}
}
private string _testName = string.Empty;
public string TestName { get => _testName; set { _testName = value; OnPropertyChanged("TestName"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private string _displayName = string.Empty;
public string DisplayName { get => _displayName; set { _displayName = value; OnPropertyChanged("DisplayName"); } }
private ObservableCollection<ITestChannel> _channels = new ObservableCollection<ITestChannel>();
public ObservableCollection<ITestChannel> Channels { get => _channels; set { _channels = value; _channelCount = _channels.Count; OnPropertyChanged("Channels"); } }
private int _channelCount = 0;
public int ChannelCount { get => _channelCount; set { _channelCount = value; OnPropertyChanged("ChannelCount"); } }
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
#endregion PropertyChanged
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.GraphList;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable UnusedParameter.Local
// ReSharper disable ConvertToAutoProperty
[assembly: GraphListNameAttribute()]
[assembly: GraphListImageAttribute()]
namespace DTS.Viewer.GraphList
{
[Module(ModuleName = "GraphList")]
public class GraphListModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="GraphListModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public GraphListModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IGraphMainView, GraphMainView>();
_unityContainer.RegisterType<IGraphMainViewModel, GraphMainViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class GraphListNameAttribute : TextAttribute
{
private readonly string _assemblyName;
public GraphListNameAttribute() : this(null) { }
public GraphListNameAttribute(string s)
{
_assemblyName = AssemblyNames.GraphList.ToString();
}
public override string AssemblyName => _assemblyName;
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class GraphListImageAttribute : ImageAttribute
{
private BitmapImage _img;
public GraphListImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString()); return _img; }
}
public GraphListImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.GraphList.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.GraphListRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,60 @@
<base:BaseView x:Class="DTS.Viewer.GraphList.ExportGraphMainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:prism="http://prismlibrary.com/"
xmlns:classes="clr-namespace:DTS.Common.Classes;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:graphList="clr-namespace:DTS.Viewer.GraphList">
<base:BaseView.Resources>
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter"/>
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<HierarchicalDataTemplate ItemsSource="{Binding Path=Events}" x:Key="Templatekey">
<StackPanel Orientation="Horizontal" Background="Transparent" AutomationProperties.AutomationId="TestContentItems">
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Margin="1,1,3,1"
AutomationProperties.AutomationId="TestChanSelectionChkBx"/>
<TextBlock Text="{Binding Path=Name}" AutomationProperties.AutomationId="TestIDNameLbl" />
</StackPanel>
</HierarchicalDataTemplate>
<SolidColorBrush Color="LightBlue" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
<Style x:Key="TvItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsSelected" Value="{Binding Path=IsSelected}"/>
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<!--<Setter Property="graphList:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
<Setter Property="graphList:VirtualToggleButton.IsLocked" Value="{Binding IsLocked}" />-->
<Setter Property="AutomationProperties.AutomationId" Value="TvTestItem" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</base:BaseView.Resources>
<Grid x:Name="GraphMainRegion" IsEnabled="{Binding TestModified, Converter={StaticResource InverseBooleanConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentControl Grid.Row="0" Content="{Binding FilterView}" IsEnabled="{Binding IsFilterEnabled}"/>
<TreeView Grid.Row="2" x:Name="TvTestIdChannels" ItemsSource="{Binding FilteredTestIdsTree}"
ItemTemplate="{StaticResource Templatekey}"
ItemContainerStyle="{StaticResource TvItemStyle}"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="{Binding ElementName=GraphMainRegion, Path=Width}" />
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,78 @@
<base:BaseView x:Class="DTS.Viewer.GraphList.GraphMainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:prism="http://prismlibrary.com/"
xmlns:classes="clr-namespace:DTS.Common.Classes;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:graphList="clr-namespace:DTS.Viewer.GraphList">
<base:BaseView.Resources>
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter"/>
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<HierarchicalDataTemplate ItemsSource="{Binding Path=Groups}" x:Key="Templatekey">
<TextBlock Text="{Binding Path=Name}" AutomationProperties.AutomationId="TestIDNameLbl" />
<HierarchicalDataTemplate.ItemTemplate >
<HierarchicalDataTemplate ItemsSource="{Binding Path=Channels}" >
<StackPanel Orientation="Horizontal" Background="Transparent" AutomationProperties.AutomationId="TestContentItems">
<CheckBox IsChecked="{Binding Path=IsLocked, Mode=TwoWay}" Margin="1,1,3,1" Visibility="{Binding Path=IsGraph, Converter={StaticResource BooleanToVisibilityConverter}, Mode=TwoWay}"
IsEnabled="{Binding Path=CanLock, Mode=TwoWay}" AutomationProperties.AutomationId="GraphChanSelectionChkBx"/>
<TextBlock VerticalAlignment="Center" Text="{Binding DisplayName}" AutomationProperties.AutomationId="TvTestViewItemNameLbl"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Opacity="{Binding Path=IsError, Converter={StaticResource BooleanToOpacityConverter}, Mode=TwoWay}"
Background="Transparent" AutomationProperties.AutomationId="ChannelItem">
<CheckBox IsChecked="{Binding Path=IsLocked, Mode=TwoWay}" Margin="0,1,3,1"
Visibility="{Binding Path=IsGraphChannel, Converter={StaticResource InverseBooleanToVisibilityConverter}, Mode=TwoWay}" Focusable="False"
IsEnabled="{Binding Path=CanLock, Mode=OneWay}" AutomationProperties.AutomationId="ChanLockChkBx"
/>
<Rectangle Width="15" Height="15" Fill="{Binding Path=ChannelColor, Converter={StaticResource ColorToSolidColorBrushConverter}, Mode=TwoWay}" Visibility="Visible" />
<TextBlock VerticalAlignment="Center" Text="{Binding Path=ChannelDisplayName}" Foreground="{Binding Path=ErrorColor, Mode=TwoWay, Converter={StaticResource ColorToSolidColorBrushConverter}}" Margin="5,0,0,0" AutomationProperties.AutomationId="ChanNameLbl"/>
<TextBlock VerticalAlignment="Center" Text="{Binding Path=ErrorMessage}" FontWeight="Bold" Foreground="{Binding Path=ErrorColor, Mode=TwoWay, Converter={StaticResource ColorToSolidColorBrushConverter}}" Margin="5,0,0,0"/>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
<SolidColorBrush Color="LightBlue" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
<Style x:Key="TvItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsSelected" Value="{Binding Path=IsSelected}"/>
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<Setter Property="graphList:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
<Setter Property="graphList:VirtualToggleButton.IsLocked" Value="{Binding IsLocked}" />
<Setter Property="AutomationProperties.AutomationId" Value="TvTestItem" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</base:BaseView.Resources>
<Grid x:Name="GraphMainRegion" IsEnabled="{Binding TestModified, Converter={StaticResource InverseBooleanConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentControl Grid.Row="0" Content="{Binding FilterView}" IsEnabled="{Binding IsFilterEnabled}"/>
<TreeView Grid.Row="1" x:Name="TvTestChannels" ItemsSource="{Binding TestChannelsTree}"
ItemTemplate="{StaticResource Templatekey}"
ItemContainerStyle="{StaticResource TvItemStyle}"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="{Binding ElementName=GraphMainRegion, Path=Width}" />
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{21253F88-41EF-4D7E-AB14-3D122253CC9F}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.GraphList</RootNamespace>
<AssemblyName>DTS.Viewer.GraphList</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\Common\DTS.Common\lib\System.Windows.Interactivity.dll</HintPath>
</Reference>
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="Xceed.Wpf.DataGrid">
<HintPath>..\..\..\Common\DTS.Common\lib\Xceed.Wpf.Toolkit\Xceed.Wpf.DataGrid.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.Toolkit">
<HintPath>..\..\..\Common\DTS.Common\lib\Xceed.Wpf.Toolkit\Xceed.Wpf.Toolkit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Classes\VirtualToggleButton.cs" />
<Compile Include="ExportGraphListModule.cs" />
<Compile Include="GraphListModule.cs" />
<Compile Include="Model\TreeViewChannels.cs" />
<Compile Include="Model\TreeViewIds.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ViewModel\ExportGraphMainViewModel.cs" />
<Compile Include="ViewModel\GraphMainViewModel.cs" />
<Compile Include="View\ExportGraphMainView.xaml.cs">
<DependentUpon>ExportGraphMainView.xaml</DependentUpon>
</Compile>
<Compile Include="View\GraphMainView.xaml.cs">
<DependentUpon>GraphMainView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="View\ExportGraphMainView.xaml">
<SubType>Designer</SubType>
<Generator>XamlIntelliSenseFileGenerator</Generator>
</Page>
<Page Include="View\GraphMainView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
<Project>{0679d014-59c2-4327-b288-0e3bd1374710}</Project>
<Name>DTS.Common.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{d6da1b74-c711-43c2-91b1-1908a8d04dbf}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,832 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
using DTS.Common.Base;
using DTS.Common.Enums.Sensors;
using DTS.Common.Events;
using DTS.Common.Interactivity;
using DTS.Common.Interface;
using DTS.Common.Interface.TestDefinition;
using DTS.Common.Strings;
using DTS.Common.Utils;
using Prism.Events;
using Prism.Regions;
using Unity;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
// ReSharper disable CheckNamespace
// ReSharper disable NotAccessedField.Local
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Local
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable RedundantAssignment
namespace DTS.Viewer.GraphList
{
public class GraphMainViewModel : BaseViewModel<IGraphMainViewModel>, IGraphMainViewModel
{
public IFilterView FilterView { get; private set; }
public IGraphMainView View { get; set; }
public IBaseViewModel Parent { get; set; }
private IEventAggregator _eventAggregator { get; set; }
private IUnityContainer _unityContainer { get; set; }
private bool _showIsoCodes = false;
public InteractionRequest<Notification> NotificationRequest { get; private set; }
public new InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
/// <summary>
/// Creates a new instance of the GraphMainViewModel.
/// </summary>
/// <param name="view">The GraphMainView interface.</param>
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
/// <param name="unityContainer">The unityContainer.</param>
public GraphMainViewModel(IGraphMainView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
: base(regionManager, eventAggregator, unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
_unityContainer = unityContainer;
}
#region Const
private const string testChannels = "Test Channels";
private const string calculatedChannels = "Calculated Channels";
private const string graphChannels = "Graph Channels: ";
#endregion
#region Colors
private readonly List<Color> _graphColors = new List<Color> { Colors.Transparent, Colors.Blue, Colors.Red, Colors.Green, Colors.BlueViolet, Colors.Brown, Colors.Aqua, Colors.Lime, Colors.Gray, Colors.YellowGreen, Colors.Black };
/// <summary>
/// Assign unused color to selected/locked channel
/// </summary>
/// <returns></returns>
private Color GetNextColor()
{
var nextColor = Colors.Transparent;
var channelCount = (LockedChannelList.Any() ? LockedChannelList.Count : 0) + (SelectedChannelList.Any() ? SelectedChannelList.Count : 0);
if (channelCount >= _graphColors.Count)
{
var nextColorIndex = channelCount % _graphColors.Count + 1;
if (nextColorIndex >= _graphColors.Count) { nextColorIndex = 1; }
nextColor = _graphColors[nextColorIndex];
}
else
{
var usedColors = new List<Color>();
usedColors.AddRange(LockedChannelList.Select(ch => ch.ChannelColor).ToList());
usedColors.AddRange(SelectedChannelList.Select(ch => ch.ChannelColor).ToList());
nextColor = _graphColors.Find(c1 => usedColors.TrueForAll(c2 => c2 != c1));
}
return nextColor;
}
#endregion
#region Methods
public override void Initialize()
{
}
private bool _lockedOnly = false; //only published locked channels
public override void Initialize(object parameter)
{
Parent = (IBaseViewModel)parameter;
if (Parent is IPSDReportMainViewModel) { _lockedOnly = true; } // only put checked channels in the report
FilterView = GetFilterView(this);
Subscribe();
}
/// <summary>
/// Reset all lists and publish changes
/// </summary>
private void CleanSelection()
{
LockedChannelList = new List<ITestChannel>();
ChannelList = new ObservableCollection<ITestChannel>();
FilteredChannelList = new ObservableCollection<ITestChannel>();
SelectedChannelList = new List<ITestChannel>();
_eventAggregator.GetEvent<GraphClearNotification>().Publish(new GraphClearNotificationArg { GraphClear = true, ParentVM = Parent });
PublishSelectedChannels();
SelectedGroupName = string.Empty;
GC.Collect();
}
/// <summary>
/// Format the Channel Display Name based on the isoCode setting
/// </summary>
/// <param name="channelName2"></param>
/// <param name="channelDescriptionString"></param>
/// <param name="isoCode"></param>
/// <returns></returns>
private string FormatChannelDisplayName(string channelName2, string channelDescriptionString, string isoCode)
{
return _showIsoCodes ? $"{channelName2} {channelDescriptionString} {Environment.NewLine} {isoCode}" : $"{channelName2} {channelDescriptionString}";
}
//hold onto the test summaries for reloads
private List<ITestSummary> testSummaries;
/// <summary>
/// Read all graphs, calculated channels and channels for the selected test
/// and select and display first group or channel
/// </summary>
/// <param name="list"></param>
private void OnTestSummaryChanged(TestSummaryChangeNotificationArg arg)
{
if (Parent != arg?.ParentVM) return;
var list = arg?.SummaryList;
testSummaries = list;
CleanSelection(); //clean every time, otherwise channels weren't being removed on test deselection
var total = 0;
if (list != null && list.Any())
{
foreach (var l in list)
{
if (l.Channels.Any() && l.Channels.FirstOrDefault() == null)
{
// LOAD NOW!
Utils.SetChannelInfo(l.TestMetadata, Path.GetDirectoryName(l.TestMetadata.TestRun.FilePath), DTS.Serialization.SliceRaw.File.PersistentChannel.GetIsoCode);
l.Channels = l.TestMetadata.TestRun.Channels;
l.Graphs = l.TestMetadata.TestSetup.TestGraphs;
l.CalculatedChannels = l.TestMetadata.TestRun.CalculatedChannels;
}
foreach (var graph in l.Graphs)
{
//12017 Viewer shows "Graphs 1/2" when there is only 1 channel
//this issue was caused by an included graph with no channels.
if (graph.ChannelIds.Any())
{
total++;
}
}
if (null != l.CalculatedChannels)
{
total += l.CalculatedChannels.Count;
}
}
}
if (list != null && list.Count <= 0) return;
var summaryList = list.ToList();
foreach (var ts in summaryList)
{
var testName = ts.Id + " " + ts.SetupName + " " + ts.DataType + " " + Utils.FormatTimeStamp(ts.TimeStamp);
if (ts.Graphs.Count > 0)
{
foreach (var graph in ts.Graphs)
{
foreach (var gch in graph.Channels.OrderBy(gch => gch.AbsoluteDisplayOrder).ThenBy(gch => gch.Number))
{
if (ChannelList.Any(x => x.Equals(gch))) continue;
gch.Group = testName;
gch.SubGroup = graphChannels + graph.Name;
gch.IsGraphChannel = true;
gch.GraphName = graph.Name;
gch.ChannelDisplayName = gch.ChannelName2 + " " + gch.ChannelDescriptionString;
gch.Parent = this;
gch.ChannelColor = Colors.Transparent;
gch.CanSelectChannel = false; gch.IsSelected = false; gch.IsLocked = false; gch.CanSelectChannel = true;
//Select first group
if (ChannelList.Count == 0) { SelectedGroupName = gch.SubGroup.Trim(); }
ChannelList.Add(gch);
}
}
}
if ((ts.CalculatedChannels != null) && (ts.CalculatedChannels.Count > 0))
{
foreach (var cch in ts.CalculatedChannels.OrderBy(cch => cch.AbsoluteDisplayOrder).ThenBy(cch => cch.Number))
{
if (ChannelList.Any(x => x.Equals(cch))) continue;
cch.Group = testName;
cch.SubGroup = calculatedChannels;
cch.IsGraphChannel = false;
cch.GraphName = string.Empty;
cch.ChannelDisplayName = cch.ChannelName2 + " " + cch.ChannelDescriptionString;
cch.IsCalculatedChannel = true;
cch.Parent = this;
cch.ChannelColor = Colors.Transparent;
cch.CanSelectChannel = false; cch.IsSelected = false; cch.IsLocked = false; cch.CanSelectChannel = true;
//Or select first calculated channel
if (ChannelList.Count == 0) { cch.IsSelected = true; }
ChannelList.Add(cch);
}
}
if (ts.Channels.Count > 0)
{
var tsChannels = ts.Channels.OrderBy(ch => ch.AbsoluteDisplayOrder).ThenBy(ch => ch.Number).ToList();
for (int i = 0; i < tsChannels.Count - 1; i++)
{
if (tsChannels[i].AbsoluteDisplayOrder == tsChannels[i + 1].AbsoluteDisplayOrder &&
tsChannels[i].Number == tsChannels[i + 1].Number)
{
switch (calibrationBehaviorSetting)
{
case CalibrationBehaviors.LinearIfAvailable:
tsChannels.RemoveAt(i);
i--;
break;
case CalibrationBehaviors.NonLinearIfAvailable:
tsChannels.RemoveAt(i + 1);
break;
case CalibrationBehaviors.UseBothIfAvailable:
tsChannels[i].ChannelDescriptionString += " (NonLinear)";
tsChannels[i + 1].ChannelDescriptionString += " (Linear)";
break;
}
}
}
total += tsChannels.Count;
foreach (var ch in tsChannels)
{
if (ChannelList.Any(x => x.Equals(ch))) continue;
ch.Group = testName;
ch.SubGroup = testChannels;
ch.IsGraphChannel = false;
ch.GraphName = string.Empty;
var channelDescription = ch.ChannelDescriptionString;
if (SensorConstants.IsTestSpecificEmbedded(channelDescription))
{
channelDescription = Strings.Table_NA;
}
ch.ChannelDisplayName = FormatChannelDisplayName(ch.ChannelName2, channelDescription, ch.IsoCode);
ch.Parent = this;
ch.ChannelColor = Colors.Transparent;
ch.CanSelectChannel = false; ch.IsSelected = false; ch.IsLocked = false; ch.CanSelectChannel = true;
//Or select first channel
if (ChannelList.Count == 0) { ch.IsSelected = true; }
ChannelList.Add(ch);
}
}
}
ChannelList.CollectionChanged += GraphList_CollectionChanged;
FilteredChannelList = new ObservableCollection<ITestChannel>(ChannelList);
TestChannelsTree.CollectionChanged += TestChannelsTree_CollectionChanged;
_eventAggregator.GetEvent<GraphLoadedCountNotification>().Publish(new GraphLoadedCountNotificationArg { LoadedCount = total, ParentVM = Parent });
if (ChannelList.Any())
{
var treeChannels = ChannelList.ToList();
TestChannelsTree = GetTestChannelsTree(treeChannels);
if (!string.IsNullOrEmpty(SelectedGroupName))
{
var group = (from t in TestChannelsTree from g in t.Groups where g.Name == SelectedGroupName.Replace(graphChannels, string.Empty) select g).FirstOrDefault();
if (group != null) { AddSelectedGroup(group); }
}
}
IsFilterEnabled = _channelList.Count > 0;
}
/// <summary>
/// Check changes to Test Modifications to see whether we need to withhold user input
/// </summary>
private void OnTestModificationsChanged(ITestModificationModel testModificationModel)
{
if (testModificationModel != null)
{
TestModified = testModificationModel.IsModified;
}
}
/// <summary>
/// Subscribe for events
/// </summary>
private void Subscribe()
{
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
_eventAggregator.GetEvent<FilterParameterChangedEvent>().Subscribe(OnFilterChanged);
_eventAggregator.GetEvent<TestSummaryChangeNotification>().Subscribe(OnTestSummaryChanged);
//_eventAggregator.GetEvent<GraphChannelsReadCompletedNotification>().Subscribe(OnReadCompletedNotification); // commented out: was noted "It does not work"
_eventAggregator.GetEvent<TestModificationChangedEvent>().Subscribe(OnTestModificationsChanged);
_eventAggregator.GetEvent<CalibrationBehaviorSettingChangedEvent>().Subscribe(OnCalibrationBehaviorSettingChanged);
_eventAggregator.GetEvent<CalibrationBehaviorSettableInViewerChangedEvent>().Subscribe(OnCalibrationBehaviorSettableInViewerChanged);
_eventAggregator.GetEvent<ChannelCodesViewChangedEvent>().Subscribe(OnChannelCodesViewChangedEvent);
}
private void OnCalibrationBehaviorSettableInViewerChanged(bool cbSettable)
{
}
private void OnChannelCodesViewChangedEvent(DTS.Common.Enums.IsoViewMode viewMode) => _showIsoCodes = (viewMode == Common.Enums.IsoViewMode.ISOAndUserCode
|| viewMode == Common.Enums.IsoViewMode.ISOOnly);
private CalibrationBehaviors calibrationBehaviorSetting { get; set; } = CalibrationBehaviors.NonLinearIfAvailable;
private void OnCalibrationBehaviorSettingChanged(CalibrationBehaviors cb)
{
calibrationBehaviorSetting = cb;
if (null != testSummaries)
{
OnTestSummaryChanged(new TestSummaryChangeNotificationArg { SummaryList = testSummaries, ParentVM = Parent });
}
}
#region Filter
/// <summary>
/// Filter Data Event
/// </summary>
/// <param name="args">Filter value</param>
public void OnFilterChanged(FilterParameterArgs args)
{
if (((IFilterViewModel)FilterView.DataContext).Parent == this)
{
FilteredChannelList = string.IsNullOrEmpty(args.Param) ? new ObservableCollection<ITestChannel>(ChannelList)
: new ObservableCollection<ITestChannel>((from x in ChannelList where x.ChannelDisplayName.ToLower().Contains(args.Param.ToLower()) select x).ToList());
}
}
#endregion Filter
#region Override
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
{
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, eventArgsWithTitle.MessageDetails, eventArgsWithTitle.Image);
NotificationRequest.Raise(new Notification
{
Content = eventArgsWithoutTitle,
Title = eventArgsWithTitle.Title
});
}
/// <summary>
/// ? I thik it's not beed used
/// </summary>
public override void Activated()
{
var fp = new FilterParameterArgs
{
Param = string.Empty,
Requester = this
};
_eventAggregator.GetEvent<FilterParameterChangedEvent>().Publish(fp);
}
#endregion Override
/// <summary>
/// Publish Locked Channels
/// </summary>
/// <summary>
/// Publish Selected and/or locked Channels
/// </summary>
public void PublishSelectedChannels()
{
var list = new List<ITestChannel>();
if (LockedChannelList.Any()) list.AddRange(LockedChannelList);
if (!_lockedOnly && SelectedChannelList.Any()) list.AddRange(SelectedChannelList);
var count = list.Count;
_eventAggregator.GetEvent<GraphSelectedChannelCountNotification>().Publish(new GraphSelectedChannelCountNotificationArg { SelectedChannelCount = count, ParentVM = Parent });
_eventAggregator.GetEvent<GraphSelectedChannelsNotification>().Publish(new GraphSelectedChannelsNotificationArg { SelectedChannels = list, ParentVM = Parent });
}
/// <summary>
/// Load Filter View
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private IFilterView GetFilterView(IBaseViewModel parent)
{
var view = _unityContainer.Resolve<IFilterView>();
var viewModel = _unityContainer.Resolve<IFilterViewModel>();
view.DataContext = viewModel;
viewModel.Initialize(parent);
return view;
}
#endregion
#region Reset Functions
private void ResetSelectedChannelColor()
{
foreach (var ch in SelectedChannelList) { if (ch.IsLocked) continue; ch.ChannelColor = Colors.Transparent; ch.CanSelectChannel = true; }
}
/// <summary>
/// Reset all selected channels prior to selecting new channel or group
/// </summary>
private void ResetSelected() { ResetSelected(string.Empty); }
private void ResetSelected(string groupName)
{
foreach (var test in TestChannelsTree)
{
foreach (var group in test.Groups)
{
if (!string.IsNullOrEmpty(groupName) && group.Name == groupName) continue;
group.IsSelected = false;
foreach (var channel in group.Channels)
{
if (channel.IsLocked) continue;
channel.CanSelectChannel = true;
channel.ChannelColor = Colors.Transparent;
}
}
}
}
#endregion Reset Functions
#region Add Selected/Locked Channel
#region Locked Channel
public void AddLockedGroupChannels(string testName, string groupName, List<ITestChannel> channels, bool isLocked)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
foreach (var channel in channels)
{
if (isLocked)
{
if (SelectedChannelList.Contains(channel)) { SelectedChannelList.Remove(channel); }
if (LockedChannelList.Contains(channel)) continue;
channel.CanSelectChannel = false;
channel.IsLocked = true;
channel.CanSelectChannel = true;
LockedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
}
else
{
if (!LockedChannelList.Contains(channel)) continue;
LockedChannelList.Remove(channel);
}
}
PublishSelectedChannels();
if (!LockedChannelList.Any() && !SelectedChannelList.Any())
{
var group = (from t in TestChannelsTree from g in t.Groups where g.TestName == testName && g.Name == groupName select g).FirstOrDefault();
if (group != null) { group.IsSelected = true; }
}
else { if (SelectedChannelList.Any()) { PublishSelectedChannels(); } }
UpdateChannelLocks();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
public void AddLockedChannel(ITestChannel channel, bool isLocked)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
if (isLocked)
{
if (SelectedChannelList.Contains(channel)) { SelectedChannelList.Remove(channel); }
if (!LockedChannelList.Contains(channel))
{
channel.CanSelectChannel = false;
channel.IsLocked = true;
channel.CanSelectChannel = true;
LockedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
}
}
else
{
if (LockedChannelList.Contains(channel))
{
LockedChannelList.Remove(channel);
}
// if there are no selected or locked channels add unlocked channel to selected list
if (!SelectedChannelList.Any())
{
if (!LockedChannelList.Exists(x => x.IsSelected)) { AddSelectedChannel(channel, true); }
}
}
UpdateChannelLocks();
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
private const int MAX_LOCKED_CHANNELS = 8;
private void UpdateChannelLocks()
{
var canLock = LockedChannelList.Count < MAX_LOCKED_CHANNELS;
foreach (var treeChannel in TestChannelsTree)
{
foreach (var group in treeChannel.Groups)
{
if (group.IsGraph)
{
if (group.IsLocked)
{
continue;
}
group.CanLock = group.Channels.Count + LockedChannelList.Count <= MAX_LOCKED_CHANNELS;
}
foreach (var channel in group.Channels)
{
if (channel.IsLocked) { continue; }
channel.CanLock = canLock;
}
}
}
}
#endregion Locked Channel
#region Selected Channel
public void AddSelectedGroupChannels(string groupName, List<ITestChannel> channels)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
ResetSelectedChannelColor();
ResetSelected(groupName);
SelectedChannelList = new List<ITestChannel>();
foreach (var channel in channels)
{
SelectedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
}
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
public void AddSelectedGroup(TestGroup group)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
group.IsSelected = true;
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
/// <summary>
/// Add selected channel to the list or select a group (graph) of channels
/// </summary>
/// <param name="channel"></param>
/// <param name="reset"></param>
public void AddSelectedChannel(ITestChannel channel, bool reset)
{
if (channel.IsLocked && LockedChannelList.Contains(channel))
{
ResetSelectedChannelColor();
SelectedChannelList = new List<ITestChannel>();
PublishSelectedChannels();
return;
}
if (channel.IsSelected && SelectedChannelList.Contains(channel)) return;
if (channel.IsGraphChannel)
{
var group = (from t in TestChannelsTree from g in t.Groups where g.TestName == channel.Group && g.Name == channel.GraphName select g).FirstOrDefault();
if (group != null) { AddSelectedGroup(group); }
}
else
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
if (reset)
{
SelectedChannelList = new List<ITestChannel>();
ResetSelected();
SelectedGroupName = string.Empty;
}
SelectedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
}
public void AddSelectedChannel(ITestChannel channel)
{
if (channel.IsLocked && LockedChannelList.Contains(channel))
{
//ResetSelected();
SelectedChannelList = new List<ITestChannel>();
PublishSelectedChannels();
return;
}
if (channel.IsSelected && SelectedChannelList.Contains(channel)) return;
if (channel.IsGraphChannel)
{
var group = (from t in TestChannelsTree from g in t.Groups where g.TestName == channel.Group && g.Name == channel.GraphName select g).FirstOrDefault();
if (group != null) { AddSelectedGroup(group); }
}
else
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
SelectedChannelList = new List<ITestChannel>();
ResetSelected();
SelectedGroupName = string.Empty;
SelectedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
}
#endregion Selected Channel
#endregion Add Selected/Locked Channel
#region ContextRegion
public object ContextGraphMainRegion
{
get => ((GraphMainView)View).GraphMainRegion.DataContext;
set { ((GraphMainView)View).GraphMainRegion.DataContext = value; OnPropertyChanged("ContextGraphMainRegion"); }
}
#endregion
#region Properties
private bool _isFilterEnabled = false;
public bool IsFilterEnabled
{
get => _isFilterEnabled;
set { _isFilterEnabled = value; OnPropertyChanged("IsFilterEnabled"); }
}
#region Selected/Locked Group
private string _selectedGroupName = string.Empty;
public string SelectedGroupName
{
get => _selectedGroupName;
set { _selectedGroupName = value; OnPropertyChanged("SelectedGroupName"); }
}
private string _lockedGroupName = string.Empty;
public string LockedGroupName
{
get => _lockedGroupName;
set { _lockedGroupName = value; OnPropertyChanged("LockedGroupName"); }
}
#endregion Selected/Locked Group
#region Lists
private List<ITestChannel> _lockedChannelList = new List<ITestChannel>();
public List<ITestChannel> LockedChannelList
{
get => _lockedChannelList;
set { _lockedChannelList = value; OnPropertyChanged("LockedChannelList"); }
}
private List<ITestChannel> _selectedChannelList = new List<ITestChannel>();
public List<ITestChannel> SelectedChannelList
{
get => _selectedChannelList;
set { _selectedChannelList = value; OnPropertyChanged("SelectedChannelList"); }
}
#endregion Lists
#region ObservableCollection
private ObservableCollection<ITestChannel> _channelList = new ObservableCollection<ITestChannel>();
public ObservableCollection<ITestChannel> ChannelList
{
get => _channelList;
set { _channelList = value; IsFilterEnabled = _channelList.Count > 0; FilteredChannelList = new ObservableCollection<ITestChannel>(_channelList); OnPropertyChanged("ChannelList"); }
}
private ObservableCollection<ITestChannel> _filteredChannelList = new ObservableCollection<ITestChannel>();
public ObservableCollection<ITestChannel> FilteredChannelList
{
get => _filteredChannelList;
set { _filteredChannelList = value; TestChannelsTree = GetTestChannelsTree(_filteredChannelList.ToList()); OnPropertyChanged("FilteredChannelList"); }
}
private ObservableCollection<TreeViewChannels> _testChannelsTree = new ObservableCollection<TreeViewChannels>();
/// <summary>
/// Main treeview object
/// </summary>
public ObservableCollection<TreeViewChannels> TestChannelsTree
{
get => _testChannelsTree;
set { _testChannelsTree = value; OnPropertyChanged("TestChannelsTree"); }
}
#endregion ObservableCollection
#region ObservableCollection Extension
public void TestChannelsTree_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null) { foreach (INotifyPropertyChanged item in e.OldItems) item.PropertyChanged -= TestChannelsTree_PropertyChanged; }
if (e.NewItems != null) { foreach (INotifyPropertyChanged item in e.NewItems) { item.PropertyChanged += TestChannelsTree_PropertyChanged; } }
}
private void TestChannelsTree_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "TestChannelsTree") { }
}
public void GraphList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null) { foreach (INotifyPropertyChanged item in e.OldItems) item.PropertyChanged -= GraphList_PropertyChanged; }
if (e.NewItems != null) { foreach (INotifyPropertyChanged item in e.NewItems) { item.PropertyChanged += GraphList_PropertyChanged; } }
}
private void GraphList_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName != "ChannelList") { } }
#endregion ObservableCollection Extension
#region PropertyChanged
///<summary>
///Occurs when a property value changes.
///</summary>
public new event PropertyChangedEventHandler PropertyChanged;
private new void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
#endregion PropertyChanged
/// <summary>
/// Gets the HeaderInfo.
/// </summary>
public string HeaderInfo => "GraphRegion";
public new bool IsBusy { get; set; }
public new bool IsDirty { get; set; }
private bool _testModified = false;
public bool TestModified { get => _testModified; set { _testModified = value; OnPropertyChanged("TestModified"); } }
#endregion
/// <summary>
/// Build the tree form list
/// </summary>
/// <param name="list">Test Channel list</param>
/// <returns>tree</returns>
private ObservableCollection<TreeViewChannels> GetTestChannelsTree(List<ITestChannel> list)
{
if (!list.Any()) return new ObservableCollection<TreeViewChannels>();
var result = (from t in list
group t.TestSetupName by t.Group into test
select new TreeViewChannels
{
Name = test.Key,
Groups = new ObservableCollection<TestGroup>(from t in list
where t.Group == test.Key
group t.Group by t.SubGroup into g
select new TestGroup
{
TestName = test.Key,
DisplayName = g.Key + " [ " + list.Count(ch => ch.Group == test.Key && ch.SubGroup == g.Key) + " Channels]",
Path = test.Key + "|" + g.Key + " [ " + list.Count(ch => ch.Group == test.Key && ch.SubGroup == g.Key) + " Channels]",
Name = g.Key.Replace(graphChannels, string.Empty),
IsGraph = g.Key.StartsWith("Graph"),
Channels = new ObservableCollection<ITestChannel>(list.Where(ch => ch.Group == test.Key && ch.SubGroup == g.Key).OrderBy(ch => ch.AbsoluteDisplayOrder).ThenBy(ch => ch.Number)),
Parent = this
})
}).ToList();
return new ObservableCollection<TreeViewChannels>(result);
}
#region Commands
#endregion Commands
}
}

View File

@@ -0,0 +1,38 @@
using System.Windows.Input;
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Interaction logic for GraphMainView.xaml
/// </summary>
public partial class GraphMainView : IGraphMainView
{
public GraphMainView()
{
InitializeComponent();
CommandBindings.Add(
new CommandBinding(
ApplicationCommands.Undo,
(sender, e) => // Execute
{
e.Handled = true;
//root.IsChecked = false;
//TvTestChannels.Focus();
},
(sender, e) => // CanExecute
{
e.Handled = true;
//e.CanExecute = (root.IsChecked != false);
}));
//TvTestChannels.Focus();
}
//public void SetTvFocus()
//{
// TvTestChannels.Focus();
//}
}
}

View File

@@ -0,0 +1,259 @@
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
public static class VirtualToggleButton
{
#region attached properties
#region IsLocked
/// <summary>
/// IsLocked Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsLockedProperty =
DependencyProperty.RegisterAttached("IsLocked", typeof(Nullable<bool>), typeof(VirtualToggleButton),
new FrameworkPropertyMetadata((Nullable<bool>)false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal,
new PropertyChangedCallback(OnIsLockedChanged)));
/// <summary>
/// Gets the IsLocked property. This dependency property
/// indicates whether the toggle button is checked.
/// </summary>
public static Nullable<bool> GetIsLocked(DependencyObject d)
{
return (Nullable<bool>)d.GetValue(IsLockedProperty);
}
/// <summary>
/// Sets the IsLocked property. This dependency property
/// indicates whether the toggle button is checked.
/// </summary>
public static void SetIsLocked(DependencyObject d, Nullable<bool> value)
{
d.SetValue(IsLockedProperty, value);
}
/// <summary>
/// Handles changes to the IsLocked property.
/// </summary>
private static void OnIsLockedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var pseudobutton = d as UIElement;
if (pseudobutton != null)
{
var newValue = (Nullable<bool>)e.NewValue;
if (newValue == true)
{
RaiseCheckedEvent(pseudobutton);
}
else if (newValue == false)
{
RaiseUncheckedEvent(pseudobutton);
}
else
{
RaiseIndeterminateEvent(pseudobutton);
}
}
}
#endregion
#region IsThreeState
/// <summary>
/// IsThreeState Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsThreeStateProperty =
DependencyProperty.RegisterAttached("IsThreeState", typeof(bool), typeof(VirtualToggleButton),
new FrameworkPropertyMetadata(false));
/// <summary>
/// Gets the IsThreeState property. This dependency property
/// indicates whether the control supports two or three states.
/// IsLocked can be set to null as a third state when IsThreeState is true.
/// </summary>
public static bool GetIsThreeState(DependencyObject d)
{
return (bool)d.GetValue(IsThreeStateProperty);
}
/// <summary>
/// Sets the IsThreeState property. This dependency property
/// indicates whether the control supports two or three states.
/// IsLocked can be set to null as a third state when IsThreeState is true.
/// </summary>
public static void SetIsThreeState(DependencyObject d, bool value)
{
d.SetValue(IsThreeStateProperty, value);
}
#endregion
#region IsVirtualToggleButton
/// <summary>
/// IsVirtualToggleButton Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsVirtualToggleButtonProperty =
DependencyProperty.RegisterAttached("IsVirtualToggleButton", typeof(bool), typeof(VirtualToggleButton),
new FrameworkPropertyMetadata(false,
new PropertyChangedCallback(OnIsVirtualToggleButtonChanged)));
/// <summary>
/// Gets the IsVirtualToggleButton property. This dependency property
/// indicates whether the object to which the property is attached is treated as a VirtualToggleButton.
/// If true, the object will respond to keyboard and mouse input the same way a ToggleButton would.
/// </summary>
public static bool GetIsVirtualToggleButton(DependencyObject d)
{
return (bool)d.GetValue(IsVirtualToggleButtonProperty);
}
/// <summary>
/// Sets the IsVirtualToggleButton property. This dependency property
/// indicates whether the object to which the property is attached is treated as a VirtualToggleButton.
/// If true, the object will respond to keyboard and mouse input the same way a ToggleButton would.
/// </summary>
public static void SetIsVirtualToggleButton(DependencyObject d, bool value)
{
d.SetValue(IsVirtualToggleButtonProperty, value);
}
/// <summary>
/// Handles changes to the IsVirtualToggleButton property.
/// </summary>
private static void OnIsVirtualToggleButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as IInputElement;
if (element != null)
{
if ((bool)e.NewValue)
{
element.MouseLeftButtonDown += OnMouseLeftButtonDown;
element.KeyDown += OnKeyDown;
}
else
{
element.MouseLeftButtonDown -= OnMouseLeftButtonDown;
element.KeyDown -= OnKeyDown;
}
}
}
#endregion
#endregion
#region routed events
#region Checked
/// <summary>
/// A static helper method to raise the Checked event on a target element.
/// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param>
internal static RoutedEventArgs RaiseCheckedEvent(UIElement target)
{
if (target == null) return null;
var args = new RoutedEventArgs { RoutedEvent = ToggleButton.CheckedEvent };
RaiseEvent(target, args);
return args;
}
#endregion
#region Unchecked
/// <summary>
/// A static helper method to raise the Unchecked event on a target element.
/// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param>
internal static RoutedEventArgs RaiseUncheckedEvent(UIElement target)
{
if (target == null) return null;
var args = new RoutedEventArgs { RoutedEvent = ToggleButton.UncheckedEvent };
RaiseEvent(target, args);
return args;
}
#endregion
#region Indeterminate
/// <summary>
/// A static helper method to raise the Indeterminate event on a target element.
/// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param>
internal static RoutedEventArgs RaiseIndeterminateEvent(UIElement target)
{
if (target == null) return null;
var args = new RoutedEventArgs { RoutedEvent = ToggleButton.IndeterminateEvent };
RaiseEvent(target, args);
return args;
}
#endregion
#endregion
#region private methods
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
UpdateIsLocked(sender as DependencyObject);
}
private static void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.OriginalSource == sender)
{
if (e.Key == Key.Space)
{
// ignore alt+space which invokes the system menu
if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) return;
UpdateIsLocked(sender as DependencyObject);
e.Handled = true;
}
else if (e.Key == Key.Enter && (bool)(sender as DependencyObject).GetValue(KeyboardNavigation.AcceptsReturnProperty))
{
UpdateIsLocked(sender as DependencyObject);
e.Handled = true;
}
}
}
private static void UpdateIsLocked(DependencyObject d)
{
var IsLocked = GetIsLocked(d);
if (IsLocked == true)
{
SetIsLocked(d, GetIsThreeState(d) ? null : (Nullable<bool>)false);
}
else
{
SetIsLocked(d, IsLocked.HasValue);
}
}
private static void RaiseEvent(DependencyObject target, RoutedEventArgs args)
{
if (target is UIElement uiElement) { uiElement.RaiseEvent(args); }
else if (target is ContentElement element) { element.RaiseEvent(args); }
}
#endregion
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.Export;
using DTS.Viewer.GraphList;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable UnusedParameter.Local
// ReSharper disable ConvertToAutoProperty
[assembly: ExportGraphListNameAttribute()]
[assembly: ExportGraphListImageAttribute()]
namespace DTS.Viewer.Export
{
[Module(ModuleName = "ExportGraphList")]
public class ExportGraphListModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="ExportGraphListModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public ExportGraphListModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IExportGraphMainView, ExportGraphMainView>();
_unityContainer.RegisterType<IExportGraphMainViewModel, ExportGraphMainViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ExportGraphListNameAttribute : TextAttribute
{
private readonly string _assemblyName;
public ExportGraphListNameAttribute() : this(null) { }
public ExportGraphListNameAttribute(string s)
{
_assemblyName = AssemblyNames.GraphList.ToString();
}
public override string AssemblyName => _assemblyName;
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ExportGraphListImageAttribute : ImageAttribute
{
private BitmapImage _img;
public ExportGraphListImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString()); return _img; }
}
public ExportGraphListImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.GraphList.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.GraphListRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,322 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows;
using DTS.Common.Base;
using DTS.Common.Interface;
using System.Windows.Media;
using System.Collections.Generic;
using System;
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Main class to bind to treeview
/// </summary>
public class TreeViewIds : IBaseModel
{
private IBaseViewModel _parent;
/// <summary>
/// Parent ViewModel
/// </summary>
public IBaseViewModel Parent { get => _parent; set { _parent = value; OnPropertyChanged("Parent"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private int _treeIndex = 0;
public int TreeIndex { get => _treeIndex; set { _treeIndex = value; OnPropertyChanged("TreeIndex"); } }
private int _eventCount = 0;
public int EventCount { get => _eventCount; set { _eventCount = value; OnPropertyChanged("EventCount"); } }
private ObservableCollection<ITestEvent> _events = new ObservableCollection<ITestEvent>();
public ObservableCollection<ITestEvent> Events { get => _events; set { _events = value; _eventCount = _events.Count; OnPropertyChanged("Events"); } }
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
public bool IsSaved { get; }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _isSelected = false;
public bool IsSelected
{
get => _isSelected;
set
{
if ((IExportGraphMainViewModel)Parent == null) return;
if (((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue && !value)
{
return;
}
if (!IsShiftPressed)
{
((IExportGraphMainViewModel)Parent).SetLastIndexChecked(TreeIndex);
}
_isSelected = value;
((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue = value;
((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes = true;
OnPropertyChanged("IsSelected");
SetChildNodes(value);
((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue = false;
((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes = false;
}
}
public void SetChildNodes(bool isSelected)
{
foreach (var node in Events)
{
node.IsSelected = isSelected;
}
}
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion PropertyChanged
public static readonly DependencyProperty IsItemSelectedProperty =
DependencyProperty.RegisterAttached("IsItemSelected", typeof(bool), typeof(TreeViewIds));
public static void SetIsItemSelected(UIElement element, bool value)
{
element.SetValue(IsItemSelectedProperty, value);
}
private static bool IsShiftPressed
{
get { return Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); }
}
private static List<TreeViewItem> GetTreeViewItems(ItemsControl parentItem, bool includeCollapsedItems, List<TreeViewItem> itemList = null)
{
if (itemList == null)
itemList = new List<TreeViewItem>();
for (var index = 0; index < parentItem.Items.Count; index++)
{
var tvItem = parentItem.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
if (tvItem == null) continue;
itemList.Add(tvItem);
if (includeCollapsedItems || tvItem.IsExpanded)
GetTreeViewItems(tvItem, includeCollapsedItems, itemList);
}
return itemList;
}
}
/// <summary>
/// Child class for TreeViewIds
/// </summary>
public class TestEvent : ITestEvent
{
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
private IBaseViewModel _parent;
/// <summary>
/// Parent ViewModel
/// </summary>
public IBaseViewModel Parent { get => _parent; set { _parent = value; OnPropertyChanged("Parent"); } }
private bool _isLocked = false;
/// <summary>
/// Locked Graph - call parent function to lock Id's events
/// </summary>
public bool IsLocked
{
get => _isLocked;
set
{
_isLocked = value;
var parent = Parent;
if (parent.GetType().GetInterfaces().Contains(typeof(IExportGraphMainViewModel))) { ((IExportGraphMainViewModel)parent).AddLockedEvents(TestName, Name, Events.ToList(), _isLocked); }
OnPropertyChanged("IsLocked");
}
}
private bool _isGraph = false;
public bool IsGraph { get => _isGraph; set { _isGraph = value; OnPropertyChanged("IsGraph"); } }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _canLock = true;
public bool CanLock
{
get => _canLock;
set
{
_canLock = value;
OnPropertyChanged("CanLock");
}
}
private static bool IsShiftPressed
{
get
{
return Keyboard.IsKeyDown(Key.LeftShift) ||
Keyboard.IsKeyDown(Key.RightShift);
}
}
private static bool IsCtrlPressed
{
get
{
return Keyboard.IsKeyDown(Key.LeftCtrl) ||
Keyboard.IsKeyDown(Key.RightCtrl);
}
}
private bool _isSelected = false;
/// <summary>
/// Selected Event - call parent function to select Id's event
/// </summary>
public bool IsSelected
{
get => _isSelected;
set => SetIsSelected(value);
}
private void SetIsSelectedShiftPressed(bool value)
{
if (IsShiftPressed &&
!((IExportGraphMainViewModel)Parent).ResettingAllItems &&
!((IExportGraphMainViewModel)Parent).SettingItemsBetween)
{
((IExportGraphMainViewModel)Parent).ResettingAllItems = true;
((IExportGraphMainViewModel)Parent).ResetAllItems();
((IExportGraphMainViewModel)Parent).ResettingAllItems = false;
}
if (IsShiftPressed &&
!((IExportGraphMainViewModel)Parent).SettingItemsBetween)
{
((IExportGraphMainViewModel)Parent).SettingItemsBetween = true;
((IExportGraphMainViewModel)Parent).SetItemsBetween(((IExportGraphMainViewModel)Parent).LastIndexChecked, TreeIndex);
((IExportGraphMainViewModel)Parent).SettingItemsBetween = false;
}
}
private bool ShouldExitSetIsSelected(bool value)
{
if (((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue && !value)
{
return true;
}
if (((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue && !value)
{
return true;
}
if (((IExportGraphMainViewModel)Parent).ResettingAllItems && value)
{
return true;
}
return false;
}
private void SetIsSelectedShiftNotPressed(bool value)
{
if (!IsShiftPressed &&
!IsCtrlPressed &&
!((IExportGraphMainViewModel)Parent).ResettingAllItems &&
!((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes)
{
((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue = false;
((IExportGraphMainViewModel)Parent).ResettingAllItems = true;
((IExportGraphMainViewModel)Parent).ResetAllItems();
((IExportGraphMainViewModel)Parent).ResettingAllItems = false;
}
}
private void SetIsSelected(bool value)
{
if (ShouldExitSetIsSelected(value)) { return; }
((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue = value;
if (IsShiftPressed) { SetIsSelectedShiftPressed(value); }
if (!IsShiftPressed && !((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes)
{
((IExportGraphMainViewModel)Parent).SetLastIndexChecked(TreeIndex);
}
if (!IsShiftPressed) { SetIsSelectedShiftNotPressed(value); }
if (!IsShiftPressed ||
(IsShiftPressed && ((IExportGraphMainViewModel)Parent).SettingItemsBetween) ||
(IsShiftPressed && ((IExportGraphMainViewModel)Parent).ResettingAllItems))
{
var prevValue = _isSelected;
_isSelected = value;
var myself = new List<ITestEvent>
{
this
};
if (IsSelected != prevValue)
{
if (IsSelected)
{
((IExportGraphMainViewModel)Parent).AddToSelectedEvents(Name, myself);
}
else
{
((IExportGraphMainViewModel)Parent).RemoveFromSelectedEvents(Name, myself);
}
}
OnPropertyChanged("IsSelected");
}
((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue = false;
}
private string _testName = string.Empty;
public string TestName { get => _testName; set { _testName = value; OnPropertyChanged("TestName"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private string _testSetupName = string.Empty;
public string TestSetupName { get => _testSetupName; set { _testSetupName = value; OnPropertyChanged("TestSetupName"); } }
private string _testItem = string.Empty;
public string TestItem { get => _testItem; set { _testItem = value; OnPropertyChanged("TestItem"); } }
private string _dtsFile = string.Empty;
public string DTSFile { get => _dtsFile; set { _dtsFile = value; OnPropertyChanged("DTSFile"); } }
private string _dataType = string.Empty;
public string DataType { get => _dataType; set { _dataType = value; OnPropertyChanged("DataType"); } }
private int _eventCount = 0;
private ObservableCollection<ITestEvent> _events = new ObservableCollection<ITestEvent>();
public ObservableCollection<ITestEvent> Events { get => _events; set { _events = value; _eventCount = _events.Count; OnPropertyChanged("Events"); } }
private string _testId = string.Empty;
public string TestId { get => _testId; set { _testId = value; OnPropertyChanged("TestId"); } }
private int _treeIndex = 0;
public int TreeIndex { get => _treeIndex; set { _treeIndex = value; OnPropertyChanged("TreeIndex"); } }
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
#endregion PropertyChanged
}
}

View File

@@ -0,0 +1,29 @@
using System.Windows.Input;
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Interaction logic for ExportGraphMainView.xaml
/// </summary>
public partial class ExportGraphMainView : IExportGraphMainView
{
public ExportGraphMainView()
{
InitializeComponent();
CommandBindings.Add(
new CommandBinding(
ApplicationCommands.Undo,
(sender, e) => // Execute
{
e.Handled = true;
},
(sender, e) => // CanExecute
{
e.Handled = true;
}));
}
}
}

View File

@@ -0,0 +1,60 @@
using System.ComponentModel;
using DTS.Common;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
namespace DTS.Viewer.GraphList.Model
{
//http://brianlagunas.com/extended-wpf-toolkitthe-updated-propertygrid/
//https://wpftoolkit.codeplex.com/wikipage?title=PropertyGrid&referringTitle=Home
public class GraphPropertyObject
{
public GraphPropertyObject() { }
#region Display Properties
[Category("Information")]
[DisplayName("Id")]
[ReadOnly(true)]
[Description("This property is read only.")]
public int Id { get; set; }
[Category("Information")]
[DisplayName("Name")]
[ReadOnly(true)]
[Description("This property is read only.")]
public string Name { get; set; }
[Category("Information")]
[DisplayName("Description")]
[ReadOnly(true)]
[Description("This property uses a TextBox as the default editor.")]
public string Description { get; set; }
[Category("Parameters")]
[DisplayName("Filter")]
[Description("This property uses a TextBox as the default editor.")]
[ItemsSource(typeof(CFCFilterItemSource))]
public string Filter { get; set; }
[Category("Parameters")]
[DisplayName("Data Flag")]
[Description("This property uses a TextBox as the default editor.")]
public string DataFlag { get; set; }
[Category("Parameters")]
[DisplayName("Shift T0 (ms)")]
[Description("This property uses a TextBox as the default editor.")]
public double ShiftT0 { get; set; }
[Category("Parameters")]
[DisplayName("EU Multiplier")]
[Description("This property uses a TextBox as the default editor.")]
public double EuMultiplier { get; set; }
[Category("Parameters")]
[DisplayName("EU Offset")]
[Description("This property uses a TextBox as the default editor.")]
public double EuOffset { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Graph")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Graph")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("61261c58-c32e-4dea-a87a-d7f956f28b4d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,76 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.ServiceProcess;
using DTS.Common;
using DTS.Common.Base;
namespace DTS.Viewer.GraphList.Model
{
public class GraphObject : IBaseClass
{
public GraphObject()
{
LoadGraphs();
}
#region Properties
private int _recId;
public int RecordId { get => _recId; set { _recId = value; OnPropertyChanged("RecordId"); } }
private int _id;
public int Id { get => _id; set { _id = value; Property.Id = _id; OnPropertyChanged("Id"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; Property.Name = value; OnPropertyChanged("Name"); } }
private string _description = string.Empty;
public string Description { get { return _description; } set { _description = value; Property.Description = _description; OnPropertyChanged("Description"); } }
private CFCFilter _filter = CFCFilter.Unfiltered;
public CFCFilter Filter { get { return _filter; } set { _filter = value; Property.Filter = _filter.ToString(); OnPropertyChanged("Filter"); } }
private string _dataFlag = string.Empty;
public string DataFlag { get { return _dataFlag; } set { _dataFlag = value; Property.DataFlag = _dataFlag; OnPropertyChanged("DataFlag"); } }
private double _shiftT0;
public double ShiftT0 { get { return _shiftT0; } set { _shiftT0 = value; Property.ShiftT0 = _shiftT0; OnPropertyChanged("ShiftT0"); } }
private double _euMultiplier;
public double EuMultiplier { get { return _euMultiplier; } set { _euMultiplier = value; Property.EuMultiplier = _euMultiplier; OnPropertyChanged("EuMultiplier"); } }
private double _euOffset;
public double EuOffset { get { return _euOffset; } set { _euOffset = value; Property.EuOffset = _euOffset; OnPropertyChanged("EuOffset"); } }
private List<double> _data = new List<double>();
public List<double> Data { get { return _data; } set { _data = value; OnPropertyChanged("Data"); } }
private bool _isVisable;
public bool Visable { get { return _isVisable; } set { _isVisable = value; OnPropertyChanged("Visable"); } }
private GraphPropertyObject _property = new GraphPropertyObject();
public GraphPropertyObject Property { get { return _property; } set { _property = value; OnPropertyChanged("Property"); } }
///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var eventHandler = PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion Properties
private void LoadGraphs()
{
//var svControllerc = new ServiceController("CPUService");
//svControllerc.ExecuteCommand(128);
}
}
}

View File

@@ -0,0 +1,259 @@
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
public static class VirtualToggleButton
{
#region attached properties
#region IsLocked
/// <summary>
/// IsLocked Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsLockedProperty =
DependencyProperty.RegisterAttached("IsLocked", typeof(Nullable<bool>), typeof(VirtualToggleButton),
new FrameworkPropertyMetadata((Nullable<bool>)false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal,
new PropertyChangedCallback(OnIsLockedChanged)));
/// <summary>
/// Gets the IsLocked property. This dependency property
/// indicates whether the toggle button is checked.
/// </summary>
public static Nullable<bool> GetIsLocked(DependencyObject d)
{
return (Nullable<bool>)d.GetValue(IsLockedProperty);
}
/// <summary>
/// Sets the IsLocked property. This dependency property
/// indicates whether the toggle button is checked.
/// </summary>
public static void SetIsLocked(DependencyObject d, Nullable<bool> value)
{
d.SetValue(IsLockedProperty, value);
}
/// <summary>
/// Handles changes to the IsLocked property.
/// </summary>
private static void OnIsLockedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var pseudobutton = d as UIElement;
if (pseudobutton != null)
{
var newValue = (Nullable<bool>)e.NewValue;
if (newValue == true)
{
RaiseCheckedEvent(pseudobutton);
}
else if (newValue == false)
{
RaiseUncheckedEvent(pseudobutton);
}
else
{
RaiseIndeterminateEvent(pseudobutton);
}
}
}
#endregion
#region IsThreeState
/// <summary>
/// IsThreeState Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsThreeStateProperty =
DependencyProperty.RegisterAttached("IsThreeState", typeof(bool), typeof(VirtualToggleButton),
new FrameworkPropertyMetadata(false));
/// <summary>
/// Gets the IsThreeState property. This dependency property
/// indicates whether the control supports two or three states.
/// IsLocked can be set to null as a third state when IsThreeState is true.
/// </summary>
public static bool GetIsThreeState(DependencyObject d)
{
return (bool)d.GetValue(IsThreeStateProperty);
}
/// <summary>
/// Sets the IsThreeState property. This dependency property
/// indicates whether the control supports two or three states.
/// IsLocked can be set to null as a third state when IsThreeState is true.
/// </summary>
public static void SetIsThreeState(DependencyObject d, bool value)
{
d.SetValue(IsThreeStateProperty, value);
}
#endregion
#region IsVirtualToggleButton
/// <summary>
/// IsVirtualToggleButton Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsVirtualToggleButtonProperty =
DependencyProperty.RegisterAttached("IsVirtualToggleButton", typeof(bool), typeof(VirtualToggleButton),
new FrameworkPropertyMetadata(false,
new PropertyChangedCallback(OnIsVirtualToggleButtonChanged)));
/// <summary>
/// Gets the IsVirtualToggleButton property. This dependency property
/// indicates whether the object to which the property is attached is treated as a VirtualToggleButton.
/// If true, the object will respond to keyboard and mouse input the same way a ToggleButton would.
/// </summary>
public static bool GetIsVirtualToggleButton(DependencyObject d)
{
return (bool)d.GetValue(IsVirtualToggleButtonProperty);
}
/// <summary>
/// Sets the IsVirtualToggleButton property. This dependency property
/// indicates whether the object to which the property is attached is treated as a VirtualToggleButton.
/// If true, the object will respond to keyboard and mouse input the same way a ToggleButton would.
/// </summary>
public static void SetIsVirtualToggleButton(DependencyObject d, bool value)
{
d.SetValue(IsVirtualToggleButtonProperty, value);
}
/// <summary>
/// Handles changes to the IsVirtualToggleButton property.
/// </summary>
private static void OnIsVirtualToggleButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as IInputElement;
if (element != null)
{
if ((bool)e.NewValue)
{
element.MouseLeftButtonDown += OnMouseLeftButtonDown;
element.KeyDown += OnKeyDown;
}
else
{
element.MouseLeftButtonDown -= OnMouseLeftButtonDown;
element.KeyDown -= OnKeyDown;
}
}
}
#endregion
#endregion
#region routed events
#region Checked
/// <summary>
/// A static helper method to raise the Checked event on a target element.
/// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param>
internal static RoutedEventArgs RaiseCheckedEvent(UIElement target)
{
if (target == null) return null;
var args = new RoutedEventArgs { RoutedEvent = ToggleButton.CheckedEvent };
RaiseEvent(target, args);
return args;
}
#endregion
#region Unchecked
/// <summary>
/// A static helper method to raise the Unchecked event on a target element.
/// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param>
internal static RoutedEventArgs RaiseUncheckedEvent(UIElement target)
{
if (target == null) return null;
var args = new RoutedEventArgs { RoutedEvent = ToggleButton.UncheckedEvent };
RaiseEvent(target, args);
return args;
}
#endregion
#region Indeterminate
/// <summary>
/// A static helper method to raise the Indeterminate event on a target element.
/// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param>
internal static RoutedEventArgs RaiseIndeterminateEvent(UIElement target)
{
if (target == null) return null;
var args = new RoutedEventArgs { RoutedEvent = ToggleButton.IndeterminateEvent };
RaiseEvent(target, args);
return args;
}
#endregion
#endregion
#region private methods
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
UpdateIsLocked(sender as DependencyObject);
}
private static void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.OriginalSource == sender)
{
if (e.Key == Key.Space)
{
// ignore alt+space which invokes the system menu
if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) return;
UpdateIsLocked(sender as DependencyObject);
e.Handled = true;
}
else if (e.Key == Key.Enter && (bool)(sender as DependencyObject).GetValue(KeyboardNavigation.AcceptsReturnProperty))
{
UpdateIsLocked(sender as DependencyObject);
e.Handled = true;
}
}
}
private static void UpdateIsLocked(DependencyObject d)
{
var IsLocked = GetIsLocked(d);
if (IsLocked == true)
{
SetIsLocked(d, GetIsThreeState(d) ? null : (Nullable<bool>)false);
}
else
{
SetIsLocked(d, IsLocked.HasValue);
}
}
private static void RaiseEvent(DependencyObject target, RoutedEventArgs args)
{
if (target is UIElement uiElement) { uiElement.RaiseEvent(args); }
else if (target is ContentElement element) { element.RaiseEvent(args); }
}
#endregion
}
}

View File

@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{21253F88-41EF-4D7E-AB14-3D122253CC9F}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.GraphList</RootNamespace>
<AssemblyName>DTS.Viewer.GraphList</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\Common\DTS.Common\lib\System.Windows.Interactivity.dll</HintPath>
</Reference>
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="Xceed.Wpf.DataGrid">
<HintPath>..\..\..\Common\DTS.Common\lib\Xceed.Wpf.Toolkit\Xceed.Wpf.DataGrid.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.Toolkit">
<HintPath>..\..\..\Common\DTS.Common\lib\Xceed.Wpf.Toolkit\Xceed.Wpf.Toolkit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Classes\VirtualToggleButton.cs" />
<Compile Include="ExportGraphListModule.cs" />
<Compile Include="GraphListModule.cs" />
<Compile Include="Model\TreeViewChannels.cs" />
<Compile Include="Model\TreeViewIds.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ViewModel\ExportGraphMainViewModel.cs" />
<Compile Include="ViewModel\GraphMainViewModel.cs" />
<Compile Include="View\ExportGraphMainView.xaml.cs">
<DependentUpon>ExportGraphMainView.xaml</DependentUpon>
</Compile>
<Compile Include="View\GraphMainView.xaml.cs">
<DependentUpon>GraphMainView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="View\ExportGraphMainView.xaml">
<SubType>Designer</SubType>
<Generator>XamlIntelliSenseFileGenerator</Generator>
</Page>
<Page Include="View\GraphMainView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
<Project>{0679d014-59c2-4327-b288-0e3bd1374710}</Project>
<Name>DTS.Common.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{d6da1b74-c711-43c2-91b1-1908a8d04dbf}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,137 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.Export;
using DTS.Viewer.GraphList;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable UnusedParameter.Local
// ReSharper disable ConvertToAutoProperty
[assembly: ExportGraphListNameAttribute()]
[assembly: ExportGraphListImageAttribute()]
namespace DTS.Viewer.Export
{
[Module(ModuleName = "ExportGraphList")]
public class ExportGraphListModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="ExportGraphListModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public ExportGraphListModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IExportGraphMainView, ExportGraphMainView>();
_unityContainer.RegisterType<IExportGraphMainViewModel, ExportGraphMainViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ExportGraphListNameAttribute : TextAttribute
{
private readonly string _assemblyName;
public ExportGraphListNameAttribute() : this(null) { }
public ExportGraphListNameAttribute(string s)
{
_assemblyName = AssemblyNames.GraphList.ToString();
}
public override string AssemblyName => _assemblyName;
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ExportGraphListImageAttribute : ImageAttribute
{
private BitmapImage _img;
public ExportGraphListImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString()); return _img; }
}
public ExportGraphListImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.GraphList.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.GraphListRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.GraphList;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable UnusedParameter.Local
// ReSharper disable ConvertToAutoProperty
[assembly: GraphListNameAttribute()]
[assembly: GraphListImageAttribute()]
namespace DTS.Viewer.GraphList
{
[Module(ModuleName = "GraphList")]
public class GraphListModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="GraphListModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public GraphListModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IGraphMainView, GraphMainView>();
_unityContainer.RegisterType<IGraphMainViewModel, GraphMainViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class GraphListNameAttribute : TextAttribute
{
private readonly string _assemblyName;
public GraphListNameAttribute() : this(null) { }
public GraphListNameAttribute(string s)
{
_assemblyName = AssemblyNames.GraphList.ToString();
}
public override string AssemblyName => _assemblyName;
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class GraphListImageAttribute : ImageAttribute
{
private BitmapImage _img;
public GraphListImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString()); return _img; }
}
public GraphListImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.GraphList.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.GraphListRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,76 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.ServiceProcess;
using DTS.Common;
using DTS.Common.Base;
namespace DTS.Viewer.GraphList.Model
{
public class GraphObject : IBaseClass
{
public GraphObject()
{
LoadGraphs();
}
#region Properties
private int _recId;
public int RecordId { get => _recId; set { _recId = value; OnPropertyChanged("RecordId"); } }
private int _id;
public int Id { get => _id; set { _id = value; Property.Id = _id; OnPropertyChanged("Id"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; Property.Name = value; OnPropertyChanged("Name"); } }
private string _description = string.Empty;
public string Description { get { return _description; } set { _description = value; Property.Description = _description; OnPropertyChanged("Description"); } }
private CFCFilter _filter = CFCFilter.Unfiltered;
public CFCFilter Filter { get { return _filter; } set { _filter = value; Property.Filter = _filter.ToString(); OnPropertyChanged("Filter"); } }
private string _dataFlag = string.Empty;
public string DataFlag { get { return _dataFlag; } set { _dataFlag = value; Property.DataFlag = _dataFlag; OnPropertyChanged("DataFlag"); } }
private double _shiftT0;
public double ShiftT0 { get { return _shiftT0; } set { _shiftT0 = value; Property.ShiftT0 = _shiftT0; OnPropertyChanged("ShiftT0"); } }
private double _euMultiplier;
public double EuMultiplier { get { return _euMultiplier; } set { _euMultiplier = value; Property.EuMultiplier = _euMultiplier; OnPropertyChanged("EuMultiplier"); } }
private double _euOffset;
public double EuOffset { get { return _euOffset; } set { _euOffset = value; Property.EuOffset = _euOffset; OnPropertyChanged("EuOffset"); } }
private List<double> _data = new List<double>();
public List<double> Data { get { return _data; } set { _data = value; OnPropertyChanged("Data"); } }
private bool _isVisable;
public bool Visable { get { return _isVisable; } set { _isVisable = value; OnPropertyChanged("Visable"); } }
private GraphPropertyObject _property = new GraphPropertyObject();
public GraphPropertyObject Property { get { return _property; } set { _property = value; OnPropertyChanged("Property"); } }
///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var eventHandler = PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion Properties
private void LoadGraphs()
{
//var svControllerc = new ServiceController("CPUService");
//svControllerc.ExecuteCommand(128);
}
}
}

View File

@@ -0,0 +1,60 @@
using System.ComponentModel;
using DTS.Common;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
namespace DTS.Viewer.GraphList.Model
{
//http://brianlagunas.com/extended-wpf-toolkitthe-updated-propertygrid/
//https://wpftoolkit.codeplex.com/wikipage?title=PropertyGrid&referringTitle=Home
public class GraphPropertyObject
{
public GraphPropertyObject() { }
#region Display Properties
[Category("Information")]
[DisplayName("Id")]
[ReadOnly(true)]
[Description("This property is read only.")]
public int Id { get; set; }
[Category("Information")]
[DisplayName("Name")]
[ReadOnly(true)]
[Description("This property is read only.")]
public string Name { get; set; }
[Category("Information")]
[DisplayName("Description")]
[ReadOnly(true)]
[Description("This property uses a TextBox as the default editor.")]
public string Description { get; set; }
[Category("Parameters")]
[DisplayName("Filter")]
[Description("This property uses a TextBox as the default editor.")]
[ItemsSource(typeof(CFCFilterItemSource))]
public string Filter { get; set; }
[Category("Parameters")]
[DisplayName("Data Flag")]
[Description("This property uses a TextBox as the default editor.")]
public string DataFlag { get; set; }
[Category("Parameters")]
[DisplayName("Shift T0 (ms)")]
[Description("This property uses a TextBox as the default editor.")]
public double ShiftT0 { get; set; }
[Category("Parameters")]
[DisplayName("EU Multiplier")]
[Description("This property uses a TextBox as the default editor.")]
public double EuMultiplier { get; set; }
[Category("Parameters")]
[DisplayName("EU Offset")]
[Description("This property uses a TextBox as the default editor.")]
public double EuOffset { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Media;
using DTS.Common.Base;
using DTS.Common.Interface;
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Main class to bind to treeview
/// </summary>
public class TreeViewChannels : IBaseModel
{
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private ObservableCollection<TestGroup> _groups = new ObservableCollection<TestGroup>();
public ObservableCollection<TestGroup> Groups { get => _groups; set { _groups = value; _groupsCount = _groups.Count; OnPropertyChanged("Groups"); } }
private int _groupsCount = 0;
public int GroupsCount { get => _groupsCount; set { _groupsCount = value; OnPropertyChanged("GroupsCount"); } }
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
public bool IsSaved { get; }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _isSelected = false;
public bool IsSelected { get => _isSelected; set { _isSelected = value; OnPropertyChanged("IsSelected"); } }
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion PropertyChanged
}
/// <summary>
/// Child class for TreeViewChannels
/// </summary>
public class TestGroup : INotifyPropertyChanged
{
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
private string _dtsFile = string.Empty;
public string DTSFile { get => _dtsFile; set { _dtsFile = value; OnPropertyChanged("DTSFile"); } }
private IBaseViewModel _parent;
/// <summary>
/// Parent ViewModel
/// </summary>
public IBaseViewModel Parent { get => _parent; set { _parent = value; OnPropertyChanged("Parent"); } }
private bool _isLocked = false;
/// <summary>
/// Locked Graph - call parent function to lock graph's channels
/// </summary>
public bool IsLocked
{
get => _isLocked;
set
{
_isLocked = value;
((IGraphMainViewModel)Parent).AddLockedGroupChannels(TestName, Name, Channels.ToList(), _isLocked);
OnPropertyChanged("IsLocked");
}
}
private bool _isGraph = false;
public bool IsGraph { get => _isGraph; set { _isGraph = value; OnPropertyChanged("IsGraph"); } }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _canLock = true;
public bool CanLock
{
get => _canLock;
set
{
_canLock = value;
OnPropertyChanged("CanLock");
}
}
private bool _isSelected = false;
/// <summary>
/// Selected Graph - call parent function to select graph's channels
/// </summary>
public bool IsSelected
{
get => _isSelected;
set
{
if (!CanLock && value)
{
return; //ignore, don't select
}
if (Name.StartsWith("Test Channels") || Name.StartsWith("Calculated Channels")) return;
var prevValue = _isSelected;
_isSelected = value;
if (IsSelected && IsSelected != prevValue) ((IGraphMainViewModel)Parent).AddSelectedGroupChannels(Name, Channels.ToList());
OnPropertyChanged("IsSelected");
}
}
private string _testName = string.Empty;
public string TestName { get => _testName; set { _testName = value; OnPropertyChanged("TestName"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private string _displayName = string.Empty;
public string DisplayName { get => _displayName; set { _displayName = value; OnPropertyChanged("DisplayName"); } }
private ObservableCollection<ITestChannel> _channels = new ObservableCollection<ITestChannel>();
public ObservableCollection<ITestChannel> Channels { get => _channels; set { _channels = value; _channelCount = _channels.Count; OnPropertyChanged("Channels"); } }
private int _channelCount = 0;
public int ChannelCount { get => _channelCount; set { _channelCount = value; OnPropertyChanged("ChannelCount"); } }
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
#endregion PropertyChanged
}
}

View File

@@ -0,0 +1,322 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows;
using DTS.Common.Base;
using DTS.Common.Interface;
using System.Windows.Media;
using System.Collections.Generic;
using System;
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Main class to bind to treeview
/// </summary>
public class TreeViewIds : IBaseModel
{
private IBaseViewModel _parent;
/// <summary>
/// Parent ViewModel
/// </summary>
public IBaseViewModel Parent { get => _parent; set { _parent = value; OnPropertyChanged("Parent"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private int _treeIndex = 0;
public int TreeIndex { get => _treeIndex; set { _treeIndex = value; OnPropertyChanged("TreeIndex"); } }
private int _eventCount = 0;
public int EventCount { get => _eventCount; set { _eventCount = value; OnPropertyChanged("EventCount"); } }
private ObservableCollection<ITestEvent> _events = new ObservableCollection<ITestEvent>();
public ObservableCollection<ITestEvent> Events { get => _events; set { _events = value; _eventCount = _events.Count; OnPropertyChanged("Events"); } }
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
public bool IsSaved { get; }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _isSelected = false;
public bool IsSelected
{
get => _isSelected;
set
{
if ((IExportGraphMainViewModel)Parent == null) return;
if (((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue && !value)
{
return;
}
if (!IsShiftPressed)
{
((IExportGraphMainViewModel)Parent).SetLastIndexChecked(TreeIndex);
}
_isSelected = value;
((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue = value;
((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes = true;
OnPropertyChanged("IsSelected");
SetChildNodes(value);
((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue = false;
((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes = false;
}
}
public void SetChildNodes(bool isSelected)
{
foreach (var node in Events)
{
node.IsSelected = isSelected;
}
}
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion PropertyChanged
public static readonly DependencyProperty IsItemSelectedProperty =
DependencyProperty.RegisterAttached("IsItemSelected", typeof(bool), typeof(TreeViewIds));
public static void SetIsItemSelected(UIElement element, bool value)
{
element.SetValue(IsItemSelectedProperty, value);
}
private static bool IsShiftPressed
{
get { return Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); }
}
private static List<TreeViewItem> GetTreeViewItems(ItemsControl parentItem, bool includeCollapsedItems, List<TreeViewItem> itemList = null)
{
if (itemList == null)
itemList = new List<TreeViewItem>();
for (var index = 0; index < parentItem.Items.Count; index++)
{
var tvItem = parentItem.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
if (tvItem == null) continue;
itemList.Add(tvItem);
if (includeCollapsedItems || tvItem.IsExpanded)
GetTreeViewItems(tvItem, includeCollapsedItems, itemList);
}
return itemList;
}
}
/// <summary>
/// Child class for TreeViewIds
/// </summary>
public class TestEvent : ITestEvent
{
private string _path = string.Empty;
public string Path { get => _path; set { _path = value; OnPropertyChanged("Path"); } }
private IBaseViewModel _parent;
/// <summary>
/// Parent ViewModel
/// </summary>
public IBaseViewModel Parent { get => _parent; set { _parent = value; OnPropertyChanged("Parent"); } }
private bool _isLocked = false;
/// <summary>
/// Locked Graph - call parent function to lock Id's events
/// </summary>
public bool IsLocked
{
get => _isLocked;
set
{
_isLocked = value;
var parent = Parent;
if (parent.GetType().GetInterfaces().Contains(typeof(IExportGraphMainViewModel))) { ((IExportGraphMainViewModel)parent).AddLockedEvents(TestName, Name, Events.ToList(), _isLocked); }
OnPropertyChanged("IsLocked");
}
}
private bool _isGraph = false;
public bool IsGraph { get => _isGraph; set { _isGraph = value; OnPropertyChanged("IsGraph"); } }
private bool _isExpanded = true;
public bool IsExpanded { get => _isExpanded; set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
private bool _canLock = true;
public bool CanLock
{
get => _canLock;
set
{
_canLock = value;
OnPropertyChanged("CanLock");
}
}
private static bool IsShiftPressed
{
get
{
return Keyboard.IsKeyDown(Key.LeftShift) ||
Keyboard.IsKeyDown(Key.RightShift);
}
}
private static bool IsCtrlPressed
{
get
{
return Keyboard.IsKeyDown(Key.LeftCtrl) ||
Keyboard.IsKeyDown(Key.RightCtrl);
}
}
private bool _isSelected = false;
/// <summary>
/// Selected Event - call parent function to select Id's event
/// </summary>
public bool IsSelected
{
get => _isSelected;
set => SetIsSelected(value);
}
private void SetIsSelectedShiftPressed(bool value)
{
if (IsShiftPressed &&
!((IExportGraphMainViewModel)Parent).ResettingAllItems &&
!((IExportGraphMainViewModel)Parent).SettingItemsBetween)
{
((IExportGraphMainViewModel)Parent).ResettingAllItems = true;
((IExportGraphMainViewModel)Parent).ResetAllItems();
((IExportGraphMainViewModel)Parent).ResettingAllItems = false;
}
if (IsShiftPressed &&
!((IExportGraphMainViewModel)Parent).SettingItemsBetween)
{
((IExportGraphMainViewModel)Parent).SettingItemsBetween = true;
((IExportGraphMainViewModel)Parent).SetItemsBetween(((IExportGraphMainViewModel)Parent).LastIndexChecked, TreeIndex);
((IExportGraphMainViewModel)Parent).SettingItemsBetween = false;
}
}
private bool ShouldExitSetIsSelected(bool value)
{
if (((IExportGraphMainViewModel)Parent).SettingChildNodesToTrue && !value)
{
return true;
}
if (((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue && !value)
{
return true;
}
if (((IExportGraphMainViewModel)Parent).ResettingAllItems && value)
{
return true;
}
return false;
}
private void SetIsSelectedShiftNotPressed(bool value)
{
if (!IsShiftPressed &&
!IsCtrlPressed &&
!((IExportGraphMainViewModel)Parent).ResettingAllItems &&
!((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes)
{
((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue = false;
((IExportGraphMainViewModel)Parent).ResettingAllItems = true;
((IExportGraphMainViewModel)Parent).ResetAllItems();
((IExportGraphMainViewModel)Parent).ResettingAllItems = false;
}
}
private void SetIsSelected(bool value)
{
if (ShouldExitSetIsSelected(value)) { return; }
((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue = value;
if (IsShiftPressed) { SetIsSelectedShiftPressed(value); }
if (!IsShiftPressed && !((IExportGraphMainViewModel)Parent).SettingOrResettingChildNodes)
{
((IExportGraphMainViewModel)Parent).SetLastIndexChecked(TreeIndex);
}
if (!IsShiftPressed) { SetIsSelectedShiftNotPressed(value); }
if (!IsShiftPressed ||
(IsShiftPressed && ((IExportGraphMainViewModel)Parent).SettingItemsBetween) ||
(IsShiftPressed && ((IExportGraphMainViewModel)Parent).ResettingAllItems))
{
var prevValue = _isSelected;
_isSelected = value;
var myself = new List<ITestEvent>
{
this
};
if (IsSelected != prevValue)
{
if (IsSelected)
{
((IExportGraphMainViewModel)Parent).AddToSelectedEvents(Name, myself);
}
else
{
((IExportGraphMainViewModel)Parent).RemoveFromSelectedEvents(Name, myself);
}
}
OnPropertyChanged("IsSelected");
}
((IExportGraphMainViewModel)Parent).SettingPeerNodeToTrue = false;
}
private string _testName = string.Empty;
public string TestName { get => _testName; set { _testName = value; OnPropertyChanged("TestName"); } }
private string _name = string.Empty;
public string Name { get => _name; set { _name = value; OnPropertyChanged("Name"); } }
private string _testSetupName = string.Empty;
public string TestSetupName { get => _testSetupName; set { _testSetupName = value; OnPropertyChanged("TestSetupName"); } }
private string _testItem = string.Empty;
public string TestItem { get => _testItem; set { _testItem = value; OnPropertyChanged("TestItem"); } }
private string _dtsFile = string.Empty;
public string DTSFile { get => _dtsFile; set { _dtsFile = value; OnPropertyChanged("DTSFile"); } }
private string _dataType = string.Empty;
public string DataType { get => _dataType; set { _dataType = value; OnPropertyChanged("DataType"); } }
private int _eventCount = 0;
private ObservableCollection<ITestEvent> _events = new ObservableCollection<ITestEvent>();
public ObservableCollection<ITestEvent> Events { get => _events; set { _events = value; _eventCount = _events.Count; OnPropertyChanged("Events"); } }
private string _testId = string.Empty;
public string TestId { get => _testId; set { _testId = value; OnPropertyChanged("TestId"); } }
private int _treeIndex = 0;
public int TreeIndex { get => _treeIndex; set { _treeIndex = value; OnPropertyChanged("TreeIndex"); } }
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
#endregion PropertyChanged
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Graph")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Graph")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("61261c58-c32e-4dea-a87a-d7f956f28b4d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,60 @@
<base:BaseView x:Class="DTS.Viewer.GraphList.ExportGraphMainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:prism="http://prismlibrary.com/"
xmlns:classes="clr-namespace:DTS.Common.Classes;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:graphList="clr-namespace:DTS.Viewer.GraphList">
<base:BaseView.Resources>
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter"/>
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<HierarchicalDataTemplate ItemsSource="{Binding Path=Events}" x:Key="Templatekey">
<StackPanel Orientation="Horizontal" Background="Transparent" AutomationProperties.AutomationId="TestContentItems">
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Margin="1,1,3,1"
AutomationProperties.AutomationId="TestChanSelectionChkBx"/>
<TextBlock Text="{Binding Path=Name}" AutomationProperties.AutomationId="TestIDNameLbl" />
</StackPanel>
</HierarchicalDataTemplate>
<SolidColorBrush Color="LightBlue" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
<Style x:Key="TvItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsSelected" Value="{Binding Path=IsSelected}"/>
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<!--<Setter Property="graphList:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
<Setter Property="graphList:VirtualToggleButton.IsLocked" Value="{Binding IsLocked}" />-->
<Setter Property="AutomationProperties.AutomationId" Value="TvTestItem" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</base:BaseView.Resources>
<Grid x:Name="GraphMainRegion" IsEnabled="{Binding TestModified, Converter={StaticResource InverseBooleanConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentControl Grid.Row="0" Content="{Binding FilterView}" IsEnabled="{Binding IsFilterEnabled}"/>
<TreeView Grid.Row="2" x:Name="TvTestIdChannels" ItemsSource="{Binding FilteredTestIdsTree}"
ItemTemplate="{StaticResource Templatekey}"
ItemContainerStyle="{StaticResource TvItemStyle}"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="{Binding ElementName=GraphMainRegion, Path=Width}" />
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,29 @@
using System.Windows.Input;
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Interaction logic for ExportGraphMainView.xaml
/// </summary>
public partial class ExportGraphMainView : IExportGraphMainView
{
public ExportGraphMainView()
{
InitializeComponent();
CommandBindings.Add(
new CommandBinding(
ApplicationCommands.Undo,
(sender, e) => // Execute
{
e.Handled = true;
},
(sender, e) => // CanExecute
{
e.Handled = true;
}));
}
}
}

View File

@@ -0,0 +1,78 @@
<base:BaseView x:Class="DTS.Viewer.GraphList.GraphMainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:prism="http://prismlibrary.com/"
xmlns:classes="clr-namespace:DTS.Common.Classes;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:graphList="clr-namespace:DTS.Viewer.GraphList">
<base:BaseView.Resources>
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter"/>
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<HierarchicalDataTemplate ItemsSource="{Binding Path=Groups}" x:Key="Templatekey">
<TextBlock Text="{Binding Path=Name}" AutomationProperties.AutomationId="TestIDNameLbl" />
<HierarchicalDataTemplate.ItemTemplate >
<HierarchicalDataTemplate ItemsSource="{Binding Path=Channels}" >
<StackPanel Orientation="Horizontal" Background="Transparent" AutomationProperties.AutomationId="TestContentItems">
<CheckBox IsChecked="{Binding Path=IsLocked, Mode=TwoWay}" Margin="1,1,3,1" Visibility="{Binding Path=IsGraph, Converter={StaticResource BooleanToVisibilityConverter}, Mode=TwoWay}"
IsEnabled="{Binding Path=CanLock, Mode=TwoWay}" AutomationProperties.AutomationId="GraphChanSelectionChkBx"/>
<TextBlock VerticalAlignment="Center" Text="{Binding DisplayName}" AutomationProperties.AutomationId="TvTestViewItemNameLbl"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Opacity="{Binding Path=IsError, Converter={StaticResource BooleanToOpacityConverter}, Mode=TwoWay}"
Background="Transparent" AutomationProperties.AutomationId="ChannelItem">
<CheckBox IsChecked="{Binding Path=IsLocked, Mode=TwoWay}" Margin="0,1,3,1"
Visibility="{Binding Path=IsGraphChannel, Converter={StaticResource InverseBooleanToVisibilityConverter}, Mode=TwoWay}" Focusable="False"
IsEnabled="{Binding Path=CanLock, Mode=OneWay}" AutomationProperties.AutomationId="ChanLockChkBx"
/>
<Rectangle Width="15" Height="15" Fill="{Binding Path=ChannelColor, Converter={StaticResource ColorToSolidColorBrushConverter}, Mode=TwoWay}" Visibility="Visible" />
<TextBlock VerticalAlignment="Center" Text="{Binding Path=ChannelDisplayName}" Foreground="{Binding Path=ErrorColor, Mode=TwoWay, Converter={StaticResource ColorToSolidColorBrushConverter}}" Margin="5,0,0,0" AutomationProperties.AutomationId="ChanNameLbl"/>
<TextBlock VerticalAlignment="Center" Text="{Binding Path=ErrorMessage}" FontWeight="Bold" Foreground="{Binding Path=ErrorColor, Mode=TwoWay, Converter={StaticResource ColorToSolidColorBrushConverter}}" Margin="5,0,0,0"/>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
<SolidColorBrush Color="LightBlue" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
<Style x:Key="TvItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsSelected" Value="{Binding Path=IsSelected}"/>
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<Setter Property="graphList:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
<Setter Property="graphList:VirtualToggleButton.IsLocked" Value="{Binding IsLocked}" />
<Setter Property="AutomationProperties.AutomationId" Value="TvTestItem" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</base:BaseView.Resources>
<Grid x:Name="GraphMainRegion" IsEnabled="{Binding TestModified, Converter={StaticResource InverseBooleanConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentControl Grid.Row="0" Content="{Binding FilterView}" IsEnabled="{Binding IsFilterEnabled}"/>
<TreeView Grid.Row="1" x:Name="TvTestChannels" ItemsSource="{Binding TestChannelsTree}"
ItemTemplate="{StaticResource Templatekey}"
ItemContainerStyle="{StaticResource TvItemStyle}"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="{Binding ElementName=GraphMainRegion, Path=Width}" />
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,38 @@
using System.Windows.Input;
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.GraphList
{
/// <summary>
/// Interaction logic for GraphMainView.xaml
/// </summary>
public partial class GraphMainView : IGraphMainView
{
public GraphMainView()
{
InitializeComponent();
CommandBindings.Add(
new CommandBinding(
ApplicationCommands.Undo,
(sender, e) => // Execute
{
e.Handled = true;
//root.IsChecked = false;
//TvTestChannels.Focus();
},
(sender, e) => // CanExecute
{
e.Handled = true;
//e.CanExecute = (root.IsChecked != false);
}));
//TvTestChannels.Focus();
}
//public void SetTvFocus()
//{
// TvTestChannels.Focus();
//}
}
}

View File

@@ -0,0 +1,832 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
using DTS.Common.Base;
using DTS.Common.Enums.Sensors;
using DTS.Common.Events;
using DTS.Common.Interactivity;
using DTS.Common.Interface;
using DTS.Common.Interface.TestDefinition;
using DTS.Common.Strings;
using DTS.Common.Utils;
using Prism.Events;
using Prism.Regions;
using Unity;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
// ReSharper disable CheckNamespace
// ReSharper disable NotAccessedField.Local
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Local
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable RedundantAssignment
namespace DTS.Viewer.GraphList
{
public class GraphMainViewModel : BaseViewModel<IGraphMainViewModel>, IGraphMainViewModel
{
public IFilterView FilterView { get; private set; }
public IGraphMainView View { get; set; }
public IBaseViewModel Parent { get; set; }
private IEventAggregator _eventAggregator { get; set; }
private IUnityContainer _unityContainer { get; set; }
private bool _showIsoCodes = false;
public InteractionRequest<Notification> NotificationRequest { get; private set; }
public new InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
/// <summary>
/// Creates a new instance of the GraphMainViewModel.
/// </summary>
/// <param name="view">The GraphMainView interface.</param>
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
/// <param name="unityContainer">The unityContainer.</param>
public GraphMainViewModel(IGraphMainView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
: base(regionManager, eventAggregator, unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
_unityContainer = unityContainer;
}
#region Const
private const string testChannels = "Test Channels";
private const string calculatedChannels = "Calculated Channels";
private const string graphChannels = "Graph Channels: ";
#endregion
#region Colors
private readonly List<Color> _graphColors = new List<Color> { Colors.Transparent, Colors.Blue, Colors.Red, Colors.Green, Colors.BlueViolet, Colors.Brown, Colors.Aqua, Colors.Lime, Colors.Gray, Colors.YellowGreen, Colors.Black };
/// <summary>
/// Assign unused color to selected/locked channel
/// </summary>
/// <returns></returns>
private Color GetNextColor()
{
var nextColor = Colors.Transparent;
var channelCount = (LockedChannelList.Any() ? LockedChannelList.Count : 0) + (SelectedChannelList.Any() ? SelectedChannelList.Count : 0);
if (channelCount >= _graphColors.Count)
{
var nextColorIndex = channelCount % _graphColors.Count + 1;
if (nextColorIndex >= _graphColors.Count) { nextColorIndex = 1; }
nextColor = _graphColors[nextColorIndex];
}
else
{
var usedColors = new List<Color>();
usedColors.AddRange(LockedChannelList.Select(ch => ch.ChannelColor).ToList());
usedColors.AddRange(SelectedChannelList.Select(ch => ch.ChannelColor).ToList());
nextColor = _graphColors.Find(c1 => usedColors.TrueForAll(c2 => c2 != c1));
}
return nextColor;
}
#endregion
#region Methods
public override void Initialize()
{
}
private bool _lockedOnly = false; //only published locked channels
public override void Initialize(object parameter)
{
Parent = (IBaseViewModel)parameter;
if (Parent is IPSDReportMainViewModel) { _lockedOnly = true; } // only put checked channels in the report
FilterView = GetFilterView(this);
Subscribe();
}
/// <summary>
/// Reset all lists and publish changes
/// </summary>
private void CleanSelection()
{
LockedChannelList = new List<ITestChannel>();
ChannelList = new ObservableCollection<ITestChannel>();
FilteredChannelList = new ObservableCollection<ITestChannel>();
SelectedChannelList = new List<ITestChannel>();
_eventAggregator.GetEvent<GraphClearNotification>().Publish(new GraphClearNotificationArg { GraphClear = true, ParentVM = Parent });
PublishSelectedChannels();
SelectedGroupName = string.Empty;
GC.Collect();
}
/// <summary>
/// Format the Channel Display Name based on the isoCode setting
/// </summary>
/// <param name="channelName2"></param>
/// <param name="channelDescriptionString"></param>
/// <param name="isoCode"></param>
/// <returns></returns>
private string FormatChannelDisplayName(string channelName2, string channelDescriptionString, string isoCode)
{
return _showIsoCodes ? $"{channelName2} {channelDescriptionString} {Environment.NewLine} {isoCode}" : $"{channelName2} {channelDescriptionString}";
}
//hold onto the test summaries for reloads
private List<ITestSummary> testSummaries;
/// <summary>
/// Read all graphs, calculated channels and channels for the selected test
/// and select and display first group or channel
/// </summary>
/// <param name="list"></param>
private void OnTestSummaryChanged(TestSummaryChangeNotificationArg arg)
{
if (Parent != arg?.ParentVM) return;
var list = arg?.SummaryList;
testSummaries = list;
CleanSelection(); //clean every time, otherwise channels weren't being removed on test deselection
var total = 0;
if (list != null && list.Any())
{
foreach (var l in list)
{
if (l.Channels.Any() && l.Channels.FirstOrDefault() == null)
{
// LOAD NOW!
Utils.SetChannelInfo(l.TestMetadata, Path.GetDirectoryName(l.TestMetadata.TestRun.FilePath), DTS.Serialization.SliceRaw.File.PersistentChannel.GetIsoCode);
l.Channels = l.TestMetadata.TestRun.Channels;
l.Graphs = l.TestMetadata.TestSetup.TestGraphs;
l.CalculatedChannels = l.TestMetadata.TestRun.CalculatedChannels;
}
foreach (var graph in l.Graphs)
{
//12017 Viewer shows "Graphs 1/2" when there is only 1 channel
//this issue was caused by an included graph with no channels.
if (graph.ChannelIds.Any())
{
total++;
}
}
if (null != l.CalculatedChannels)
{
total += l.CalculatedChannels.Count;
}
}
}
if (list != null && list.Count <= 0) return;
var summaryList = list.ToList();
foreach (var ts in summaryList)
{
var testName = ts.Id + " " + ts.SetupName + " " + ts.DataType + " " + Utils.FormatTimeStamp(ts.TimeStamp);
if (ts.Graphs.Count > 0)
{
foreach (var graph in ts.Graphs)
{
foreach (var gch in graph.Channels.OrderBy(gch => gch.AbsoluteDisplayOrder).ThenBy(gch => gch.Number))
{
if (ChannelList.Any(x => x.Equals(gch))) continue;
gch.Group = testName;
gch.SubGroup = graphChannels + graph.Name;
gch.IsGraphChannel = true;
gch.GraphName = graph.Name;
gch.ChannelDisplayName = gch.ChannelName2 + " " + gch.ChannelDescriptionString;
gch.Parent = this;
gch.ChannelColor = Colors.Transparent;
gch.CanSelectChannel = false; gch.IsSelected = false; gch.IsLocked = false; gch.CanSelectChannel = true;
//Select first group
if (ChannelList.Count == 0) { SelectedGroupName = gch.SubGroup.Trim(); }
ChannelList.Add(gch);
}
}
}
if ((ts.CalculatedChannels != null) && (ts.CalculatedChannels.Count > 0))
{
foreach (var cch in ts.CalculatedChannels.OrderBy(cch => cch.AbsoluteDisplayOrder).ThenBy(cch => cch.Number))
{
if (ChannelList.Any(x => x.Equals(cch))) continue;
cch.Group = testName;
cch.SubGroup = calculatedChannels;
cch.IsGraphChannel = false;
cch.GraphName = string.Empty;
cch.ChannelDisplayName = cch.ChannelName2 + " " + cch.ChannelDescriptionString;
cch.IsCalculatedChannel = true;
cch.Parent = this;
cch.ChannelColor = Colors.Transparent;
cch.CanSelectChannel = false; cch.IsSelected = false; cch.IsLocked = false; cch.CanSelectChannel = true;
//Or select first calculated channel
if (ChannelList.Count == 0) { cch.IsSelected = true; }
ChannelList.Add(cch);
}
}
if (ts.Channels.Count > 0)
{
var tsChannels = ts.Channels.OrderBy(ch => ch.AbsoluteDisplayOrder).ThenBy(ch => ch.Number).ToList();
for (int i = 0; i < tsChannels.Count - 1; i++)
{
if (tsChannels[i].AbsoluteDisplayOrder == tsChannels[i + 1].AbsoluteDisplayOrder &&
tsChannels[i].Number == tsChannels[i + 1].Number)
{
switch (calibrationBehaviorSetting)
{
case CalibrationBehaviors.LinearIfAvailable:
tsChannels.RemoveAt(i);
i--;
break;
case CalibrationBehaviors.NonLinearIfAvailable:
tsChannels.RemoveAt(i + 1);
break;
case CalibrationBehaviors.UseBothIfAvailable:
tsChannels[i].ChannelDescriptionString += " (NonLinear)";
tsChannels[i + 1].ChannelDescriptionString += " (Linear)";
break;
}
}
}
total += tsChannels.Count;
foreach (var ch in tsChannels)
{
if (ChannelList.Any(x => x.Equals(ch))) continue;
ch.Group = testName;
ch.SubGroup = testChannels;
ch.IsGraphChannel = false;
ch.GraphName = string.Empty;
var channelDescription = ch.ChannelDescriptionString;
if (SensorConstants.IsTestSpecificEmbedded(channelDescription))
{
channelDescription = Strings.Table_NA;
}
ch.ChannelDisplayName = FormatChannelDisplayName(ch.ChannelName2, channelDescription, ch.IsoCode);
ch.Parent = this;
ch.ChannelColor = Colors.Transparent;
ch.CanSelectChannel = false; ch.IsSelected = false; ch.IsLocked = false; ch.CanSelectChannel = true;
//Or select first channel
if (ChannelList.Count == 0) { ch.IsSelected = true; }
ChannelList.Add(ch);
}
}
}
ChannelList.CollectionChanged += GraphList_CollectionChanged;
FilteredChannelList = new ObservableCollection<ITestChannel>(ChannelList);
TestChannelsTree.CollectionChanged += TestChannelsTree_CollectionChanged;
_eventAggregator.GetEvent<GraphLoadedCountNotification>().Publish(new GraphLoadedCountNotificationArg { LoadedCount = total, ParentVM = Parent });
if (ChannelList.Any())
{
var treeChannels = ChannelList.ToList();
TestChannelsTree = GetTestChannelsTree(treeChannels);
if (!string.IsNullOrEmpty(SelectedGroupName))
{
var group = (from t in TestChannelsTree from g in t.Groups where g.Name == SelectedGroupName.Replace(graphChannels, string.Empty) select g).FirstOrDefault();
if (group != null) { AddSelectedGroup(group); }
}
}
IsFilterEnabled = _channelList.Count > 0;
}
/// <summary>
/// Check changes to Test Modifications to see whether we need to withhold user input
/// </summary>
private void OnTestModificationsChanged(ITestModificationModel testModificationModel)
{
if (testModificationModel != null)
{
TestModified = testModificationModel.IsModified;
}
}
/// <summary>
/// Subscribe for events
/// </summary>
private void Subscribe()
{
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
_eventAggregator.GetEvent<FilterParameterChangedEvent>().Subscribe(OnFilterChanged);
_eventAggregator.GetEvent<TestSummaryChangeNotification>().Subscribe(OnTestSummaryChanged);
//_eventAggregator.GetEvent<GraphChannelsReadCompletedNotification>().Subscribe(OnReadCompletedNotification); // commented out: was noted "It does not work"
_eventAggregator.GetEvent<TestModificationChangedEvent>().Subscribe(OnTestModificationsChanged);
_eventAggregator.GetEvent<CalibrationBehaviorSettingChangedEvent>().Subscribe(OnCalibrationBehaviorSettingChanged);
_eventAggregator.GetEvent<CalibrationBehaviorSettableInViewerChangedEvent>().Subscribe(OnCalibrationBehaviorSettableInViewerChanged);
_eventAggregator.GetEvent<ChannelCodesViewChangedEvent>().Subscribe(OnChannelCodesViewChangedEvent);
}
private void OnCalibrationBehaviorSettableInViewerChanged(bool cbSettable)
{
}
private void OnChannelCodesViewChangedEvent(DTS.Common.Enums.IsoViewMode viewMode) => _showIsoCodes = (viewMode == Common.Enums.IsoViewMode.ISOAndUserCode
|| viewMode == Common.Enums.IsoViewMode.ISOOnly);
private CalibrationBehaviors calibrationBehaviorSetting { get; set; } = CalibrationBehaviors.NonLinearIfAvailable;
private void OnCalibrationBehaviorSettingChanged(CalibrationBehaviors cb)
{
calibrationBehaviorSetting = cb;
if (null != testSummaries)
{
OnTestSummaryChanged(new TestSummaryChangeNotificationArg { SummaryList = testSummaries, ParentVM = Parent });
}
}
#region Filter
/// <summary>
/// Filter Data Event
/// </summary>
/// <param name="args">Filter value</param>
public void OnFilterChanged(FilterParameterArgs args)
{
if (((IFilterViewModel)FilterView.DataContext).Parent == this)
{
FilteredChannelList = string.IsNullOrEmpty(args.Param) ? new ObservableCollection<ITestChannel>(ChannelList)
: new ObservableCollection<ITestChannel>((from x in ChannelList where x.ChannelDisplayName.ToLower().Contains(args.Param.ToLower()) select x).ToList());
}
}
#endregion Filter
#region Override
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
{
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, eventArgsWithTitle.MessageDetails, eventArgsWithTitle.Image);
NotificationRequest.Raise(new Notification
{
Content = eventArgsWithoutTitle,
Title = eventArgsWithTitle.Title
});
}
/// <summary>
/// ? I thik it's not beed used
/// </summary>
public override void Activated()
{
var fp = new FilterParameterArgs
{
Param = string.Empty,
Requester = this
};
_eventAggregator.GetEvent<FilterParameterChangedEvent>().Publish(fp);
}
#endregion Override
/// <summary>
/// Publish Locked Channels
/// </summary>
/// <summary>
/// Publish Selected and/or locked Channels
/// </summary>
public void PublishSelectedChannels()
{
var list = new List<ITestChannel>();
if (LockedChannelList.Any()) list.AddRange(LockedChannelList);
if (!_lockedOnly && SelectedChannelList.Any()) list.AddRange(SelectedChannelList);
var count = list.Count;
_eventAggregator.GetEvent<GraphSelectedChannelCountNotification>().Publish(new GraphSelectedChannelCountNotificationArg { SelectedChannelCount = count, ParentVM = Parent });
_eventAggregator.GetEvent<GraphSelectedChannelsNotification>().Publish(new GraphSelectedChannelsNotificationArg { SelectedChannels = list, ParentVM = Parent });
}
/// <summary>
/// Load Filter View
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private IFilterView GetFilterView(IBaseViewModel parent)
{
var view = _unityContainer.Resolve<IFilterView>();
var viewModel = _unityContainer.Resolve<IFilterViewModel>();
view.DataContext = viewModel;
viewModel.Initialize(parent);
return view;
}
#endregion
#region Reset Functions
private void ResetSelectedChannelColor()
{
foreach (var ch in SelectedChannelList) { if (ch.IsLocked) continue; ch.ChannelColor = Colors.Transparent; ch.CanSelectChannel = true; }
}
/// <summary>
/// Reset all selected channels prior to selecting new channel or group
/// </summary>
private void ResetSelected() { ResetSelected(string.Empty); }
private void ResetSelected(string groupName)
{
foreach (var test in TestChannelsTree)
{
foreach (var group in test.Groups)
{
if (!string.IsNullOrEmpty(groupName) && group.Name == groupName) continue;
group.IsSelected = false;
foreach (var channel in group.Channels)
{
if (channel.IsLocked) continue;
channel.CanSelectChannel = true;
channel.ChannelColor = Colors.Transparent;
}
}
}
}
#endregion Reset Functions
#region Add Selected/Locked Channel
#region Locked Channel
public void AddLockedGroupChannels(string testName, string groupName, List<ITestChannel> channels, bool isLocked)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
foreach (var channel in channels)
{
if (isLocked)
{
if (SelectedChannelList.Contains(channel)) { SelectedChannelList.Remove(channel); }
if (LockedChannelList.Contains(channel)) continue;
channel.CanSelectChannel = false;
channel.IsLocked = true;
channel.CanSelectChannel = true;
LockedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
}
else
{
if (!LockedChannelList.Contains(channel)) continue;
LockedChannelList.Remove(channel);
}
}
PublishSelectedChannels();
if (!LockedChannelList.Any() && !SelectedChannelList.Any())
{
var group = (from t in TestChannelsTree from g in t.Groups where g.TestName == testName && g.Name == groupName select g).FirstOrDefault();
if (group != null) { group.IsSelected = true; }
}
else { if (SelectedChannelList.Any()) { PublishSelectedChannels(); } }
UpdateChannelLocks();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
public void AddLockedChannel(ITestChannel channel, bool isLocked)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
if (isLocked)
{
if (SelectedChannelList.Contains(channel)) { SelectedChannelList.Remove(channel); }
if (!LockedChannelList.Contains(channel))
{
channel.CanSelectChannel = false;
channel.IsLocked = true;
channel.CanSelectChannel = true;
LockedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
}
}
else
{
if (LockedChannelList.Contains(channel))
{
LockedChannelList.Remove(channel);
}
// if there are no selected or locked channels add unlocked channel to selected list
if (!SelectedChannelList.Any())
{
if (!LockedChannelList.Exists(x => x.IsSelected)) { AddSelectedChannel(channel, true); }
}
}
UpdateChannelLocks();
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
private const int MAX_LOCKED_CHANNELS = 8;
private void UpdateChannelLocks()
{
var canLock = LockedChannelList.Count < MAX_LOCKED_CHANNELS;
foreach (var treeChannel in TestChannelsTree)
{
foreach (var group in treeChannel.Groups)
{
if (group.IsGraph)
{
if (group.IsLocked)
{
continue;
}
group.CanLock = group.Channels.Count + LockedChannelList.Count <= MAX_LOCKED_CHANNELS;
}
foreach (var channel in group.Channels)
{
if (channel.IsLocked) { continue; }
channel.CanLock = canLock;
}
}
}
}
#endregion Locked Channel
#region Selected Channel
public void AddSelectedGroupChannels(string groupName, List<ITestChannel> channels)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
ResetSelectedChannelColor();
ResetSelected(groupName);
SelectedChannelList = new List<ITestChannel>();
foreach (var channel in channels)
{
SelectedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
}
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
public void AddSelectedGroup(TestGroup group)
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
group.IsSelected = true;
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
/// <summary>
/// Add selected channel to the list or select a group (graph) of channels
/// </summary>
/// <param name="channel"></param>
/// <param name="reset"></param>
public void AddSelectedChannel(ITestChannel channel, bool reset)
{
if (channel.IsLocked && LockedChannelList.Contains(channel))
{
ResetSelectedChannelColor();
SelectedChannelList = new List<ITestChannel>();
PublishSelectedChannels();
return;
}
if (channel.IsSelected && SelectedChannelList.Contains(channel)) return;
if (channel.IsGraphChannel)
{
var group = (from t in TestChannelsTree from g in t.Groups where g.TestName == channel.Group && g.Name == channel.GraphName select g).FirstOrDefault();
if (group != null) { AddSelectedGroup(group); }
}
else
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
if (reset)
{
SelectedChannelList = new List<ITestChannel>();
ResetSelected();
SelectedGroupName = string.Empty;
}
SelectedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
}
public void AddSelectedChannel(ITestChannel channel)
{
if (channel.IsLocked && LockedChannelList.Contains(channel))
{
//ResetSelected();
SelectedChannelList = new List<ITestChannel>();
PublishSelectedChannels();
return;
}
if (channel.IsSelected && SelectedChannelList.Contains(channel)) return;
if (channel.IsGraphChannel)
{
var group = (from t in TestChannelsTree from g in t.Groups where g.TestName == channel.Group && g.Name == channel.GraphName select g).FirstOrDefault();
if (group != null) { AddSelectedGroup(group); }
}
else
{
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
SelectedChannelList = new List<ITestChannel>();
ResetSelected();
SelectedGroupName = string.Empty;
SelectedChannelList.Add(channel);
if (channel.ChannelColor == Colors.Transparent) { channel.ChannelColor = GetNextColor(); }
PublishSelectedChannels();
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
}
}
#endregion Selected Channel
#endregion Add Selected/Locked Channel
#region ContextRegion
public object ContextGraphMainRegion
{
get => ((GraphMainView)View).GraphMainRegion.DataContext;
set { ((GraphMainView)View).GraphMainRegion.DataContext = value; OnPropertyChanged("ContextGraphMainRegion"); }
}
#endregion
#region Properties
private bool _isFilterEnabled = false;
public bool IsFilterEnabled
{
get => _isFilterEnabled;
set { _isFilterEnabled = value; OnPropertyChanged("IsFilterEnabled"); }
}
#region Selected/Locked Group
private string _selectedGroupName = string.Empty;
public string SelectedGroupName
{
get => _selectedGroupName;
set { _selectedGroupName = value; OnPropertyChanged("SelectedGroupName"); }
}
private string _lockedGroupName = string.Empty;
public string LockedGroupName
{
get => _lockedGroupName;
set { _lockedGroupName = value; OnPropertyChanged("LockedGroupName"); }
}
#endregion Selected/Locked Group
#region Lists
private List<ITestChannel> _lockedChannelList = new List<ITestChannel>();
public List<ITestChannel> LockedChannelList
{
get => _lockedChannelList;
set { _lockedChannelList = value; OnPropertyChanged("LockedChannelList"); }
}
private List<ITestChannel> _selectedChannelList = new List<ITestChannel>();
public List<ITestChannel> SelectedChannelList
{
get => _selectedChannelList;
set { _selectedChannelList = value; OnPropertyChanged("SelectedChannelList"); }
}
#endregion Lists
#region ObservableCollection
private ObservableCollection<ITestChannel> _channelList = new ObservableCollection<ITestChannel>();
public ObservableCollection<ITestChannel> ChannelList
{
get => _channelList;
set { _channelList = value; IsFilterEnabled = _channelList.Count > 0; FilteredChannelList = new ObservableCollection<ITestChannel>(_channelList); OnPropertyChanged("ChannelList"); }
}
private ObservableCollection<ITestChannel> _filteredChannelList = new ObservableCollection<ITestChannel>();
public ObservableCollection<ITestChannel> FilteredChannelList
{
get => _filteredChannelList;
set { _filteredChannelList = value; TestChannelsTree = GetTestChannelsTree(_filteredChannelList.ToList()); OnPropertyChanged("FilteredChannelList"); }
}
private ObservableCollection<TreeViewChannels> _testChannelsTree = new ObservableCollection<TreeViewChannels>();
/// <summary>
/// Main treeview object
/// </summary>
public ObservableCollection<TreeViewChannels> TestChannelsTree
{
get => _testChannelsTree;
set { _testChannelsTree = value; OnPropertyChanged("TestChannelsTree"); }
}
#endregion ObservableCollection
#region ObservableCollection Extension
public void TestChannelsTree_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null) { foreach (INotifyPropertyChanged item in e.OldItems) item.PropertyChanged -= TestChannelsTree_PropertyChanged; }
if (e.NewItems != null) { foreach (INotifyPropertyChanged item in e.NewItems) { item.PropertyChanged += TestChannelsTree_PropertyChanged; } }
}
private void TestChannelsTree_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "TestChannelsTree") { }
}
public void GraphList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null) { foreach (INotifyPropertyChanged item in e.OldItems) item.PropertyChanged -= GraphList_PropertyChanged; }
if (e.NewItems != null) { foreach (INotifyPropertyChanged item in e.NewItems) { item.PropertyChanged += GraphList_PropertyChanged; } }
}
private void GraphList_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName != "ChannelList") { } }
#endregion ObservableCollection Extension
#region PropertyChanged
///<summary>
///Occurs when a property value changes.
///</summary>
public new event PropertyChangedEventHandler PropertyChanged;
private new void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
#endregion PropertyChanged
/// <summary>
/// Gets the HeaderInfo.
/// </summary>
public string HeaderInfo => "GraphRegion";
public new bool IsBusy { get; set; }
public new bool IsDirty { get; set; }
private bool _testModified = false;
public bool TestModified { get => _testModified; set { _testModified = value; OnPropertyChanged("TestModified"); } }
#endregion
/// <summary>
/// Build the tree form list
/// </summary>
/// <param name="list">Test Channel list</param>
/// <returns>tree</returns>
private ObservableCollection<TreeViewChannels> GetTestChannelsTree(List<ITestChannel> list)
{
if (!list.Any()) return new ObservableCollection<TreeViewChannels>();
var result = (from t in list
group t.TestSetupName by t.Group into test
select new TreeViewChannels
{
Name = test.Key,
Groups = new ObservableCollection<TestGroup>(from t in list
where t.Group == test.Key
group t.Group by t.SubGroup into g
select new TestGroup
{
TestName = test.Key,
DisplayName = g.Key + " [ " + list.Count(ch => ch.Group == test.Key && ch.SubGroup == g.Key) + " Channels]",
Path = test.Key + "|" + g.Key + " [ " + list.Count(ch => ch.Group == test.Key && ch.SubGroup == g.Key) + " Channels]",
Name = g.Key.Replace(graphChannels, string.Empty),
IsGraph = g.Key.StartsWith("Graph"),
Channels = new ObservableCollection<ITestChannel>(list.Where(ch => ch.Group == test.Key && ch.SubGroup == g.Key).OrderBy(ch => ch.AbsoluteDisplayOrder).ThenBy(ch => ch.Number)),
Parent = this
})
}).ToList();
return new ObservableCollection<TreeViewChannels>(result);
}
#region Commands
#endregion Commands
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]