diff options
10 files changed, 437 insertions, 7 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogView.xaml new file mode 100644 index 000000000..10af90ce3 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogView.xaml @@ -0,0 +1,65 @@ +<UserControl x:Class="Tango.FSE.Insights.Dialogs.ExportToCsvDialogView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" + xmlns:local="clr-namespace:Tango.FSE.Insights.Dialogs" + mc:Ignorable="d" + Width="700" Height="500" d:DataContext="{d:DesignInstance Type=local:ExportToCsvDialogViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + <Grid Margin="10"> + <DockPanel> + <StackPanel DockPanel.Dock="Top" > + <StackPanel Orientation="Horizontal"> + <Image Source="../Images/excel.png" Stretch="Uniform" Width="50" RenderOptions.BitmapScalingMode="Fant" /> + <TextBlock Margin="10 0 0 0" FontSize="{StaticResource FSE_LargerFontSize}" VerticalAlignment="Center">Export Monitors To CSV</TextBlock> + </StackPanel> + + <TextBlock Margin="0 10 0 0" TextWrapping="Wrap" FontSize="{StaticResource FSE_SmallFontSize}"> + <Run>Please select from the below monitors and press 'EXPORT'.</Run> + <LineBreak/> + <Run Foreground="{StaticResource FSE_GrayBrush}">Gaps in monitors samples due to machine disconnection etc, will be represented by a row with empty values.</Run> + </TextBlock> + + <DockPanel Margin="0 10 0 0"> + <material:PackIcon Kind="Search" VerticalAlignment="Center" Width="20" Height="20" /> + <TextBox Margin="5 0 0 0" Padding="1" material:HintAssist.Hint="Find Monitor" Text="{Binding Filter,UpdateSourceTrigger=PropertyChanged,Delay=300}" Width="300" HorizontalAlignment="Left"></TextBox> + </DockPanel> + </StackPanel> + + <DockPanel> + <StackPanel DockPanel.Dock="Bottom" Margin="0 10 0 0"> + <DockPanel> + <commonControls:IconButton Command="{Binding SelectFileCommand}" Margin="5 0 0 0" Padding="0" DockPanel.Dock="Right" Icon="FolderOpen" Width="30" Height="30" VerticalAlignment="Bottom" /> + <TextBox Style="{StaticResource FSE_Rounded_Corners_TextBox}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" material:HintAssist.Hint="Browse File Location" Text="{Binding SelectedFile,Mode=OneWay}" IsReadOnly="True"></TextBox> + </DockPanel> + </StackPanel> + <Border Margin="0 10 0 0" BorderThickness="1" BorderBrush="{StaticResource FSE_BorderBrush}" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" CornerRadius="5"> + <ScrollViewer Margin="2" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"> + <StackPanel> + <StackPanel Orientation="Horizontal" Margin="5 5 0 0"> + <CheckBox VerticalAlignment="Center" IsChecked="{Binding SelectAll,Mode=TwoWay}" /> + <material:PackIcon Margin="5 0 0 0" VerticalAlignment="Center" Kind="ChartHistogram" Width="20" Height="20" /> + <TextBlock Margin="10 0 0 0" Text="Select All" VerticalAlignment="Center"></TextBlock> + </StackPanel> + <ItemsControl ItemsSource="{Binding SelectedCharts}"> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Border Padding="5"> + <StackPanel Orientation="Horizontal"> + <CheckBox VerticalAlignment="Center" IsChecked="{Binding IsSelected,Mode=TwoWay}" /> + <material:PackIcon Margin="5 0 0 0" VerticalAlignment="Center" Kind="ChartLine" Width="20" Height="20" /> + <TextBlock Margin="10 0 0 0" Text="{Binding Data.Description}" VerticalAlignment="Center"></TextBlock> + </StackPanel> + </Border> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </StackPanel> + </ScrollViewer> + </Border> + </DockPanel> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogView.xaml.cs new file mode 100644 index 000000000..6df209bb1 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.FSE.Insights.Dialogs +{ + /// <summary> + /// Interaction logic for ExportToCsvDialogView.xaml + /// </summary> + public partial class ExportToCsvDialogView : UserControl + { + public ExportToCsvDialogView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogViewVM.cs new file mode 100644 index 000000000..4b75ea6fd --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Dialogs/ExportToCsvDialogViewVM.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.FSE.Common; +using Tango.FSE.Common.Storage; +using Tango.FSE.Insights.SciChart; +using Tango.SharedUI.Components; + +namespace Tango.FSE.Insights.Dialogs +{ + public class ExportToCsvDialogViewVM : FSEDialogViewVM + { + private ICollectionView _view; + private bool _preventSelectAllChange; + + [TangoInject] + private IStorageProvider StorageProvider { get; set; } + + public SelectedObjectCollection<InsightsChart> SelectedCharts { get; set; } + + private String _filter; + public String Filter + { + get { return _filter; } + set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool? _selectAll; + public bool? SelectAll + { + get { return _selectAll; } + set + { + if (_selectAll != value) + { + _selectAll = value; + RaisePropertyChangedAuto(); + OnSelectAllChanged(); + } + } + } + + private String _selectedFile; + public String SelectedFile + { + get { return _selectedFile; } + set { _selectedFile = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + public RelayCommand SelectFileCommand { get; set; } + + public ExportToCsvDialogViewVM(List<InsightsChart> availableCharts, List<InsightsChart> visibleCharts) + { + TangoIOC.Default.Inject(this); + + OKText = "EXPORT"; + SelectedCharts = new SelectedObjectCollection<InsightsChart>(availableCharts.OrderByDescending(x => visibleCharts.Contains(x)).ToObservableCollection(), visibleCharts.ToObservableCollection()); + SelectedCharts.SelectionChanged += SelectedCharts_SelectionChanged; + + _view = CollectionViewSource.GetDefaultView(SelectedCharts); + _view.Filter = FilterCharts; + + SelectFileCommand = new RelayCommand(SelectFile); + } + + private async void SelectFile() + { + var result = await StorageProvider.SaveFile("Export Monitors CSV", "CSV Files|*.csv", null, ".csv"); + + if (result.Confirmed) + { + SelectedFile = result.SelectedItem; + } + } + + private bool FilterCharts(object obj) + { + if (String.IsNullOrWhiteSpace(Filter)) return true; + return (obj as SelectedObject<InsightsChart>).Data.Description.ToLower().Contains(Filter.ToLower()); + } + + private void SelectedCharts_SelectionChanged(object sender, EventArgs e) + { + if (!_preventSelectAllChange) + { + if (SelectedCharts.All(x => x.IsSelected)) + { + _selectAll = true; + } + else if (SelectedCharts.Any(x => x.IsSelected)) + { + _selectAll = null; + } + else + { + _selectAll = false; + } + } + + RaisePropertyChanged(nameof(SelectAll)); + + InvalidateRelayCommands(); + } + + protected override bool CanOK() + { + return base.CanOK() && SelectedCharts.SynchedSource.Count > 0 && SelectedFile != null; + } + + private void OnFilterChanged() + { + _view?.Refresh(); + } + + private void OnSelectAllChanged() + { + if (SelectAll != null) + { + _preventSelectAllChange = true; + SelectedCharts.ToList().ForEach(x => x.IsSelected = SelectAll.Value); + _preventSelectAllChange = false; + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Images/excel.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Images/excel.png Binary files differnew file mode 100644 index 000000000..74f67b9df --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Images/excel.png diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Tango.FSE.Insights.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Tango.FSE.Insights.csproj index 3130e4c3b..63ba49c7a 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Tango.FSE.Insights.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Tango.FSE.Insights.csproj @@ -167,6 +167,10 @@ <DependentUpon>AnomaliesDialogView.xaml</DependentUpon> </Compile> <Compile Include="Dialogs\AnomaliesDialogViewVM.cs" /> + <Compile Include="Dialogs\ExportToCsvDialogView.xaml.cs"> + <DependentUpon>ExportToCsvDialogView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\ExportToCsvDialogViewVM.cs" /> <Compile Include="InsightsSettings.cs" /> <Compile Include="ML\AnomaliesDetectionProgress.cs" /> <Compile Include="ML\AnomaliesDetector.cs" /> @@ -227,6 +231,10 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\..\Tango.CSV\Tango.CSV.csproj"> + <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> <ProjectReference Include="..\..\..\Tango.Insights\Tango.Insights.csproj"> <Project>{4a55c185-3f8d-41b0-8815-c15f6213a14a}</Project> <Name>Tango.Insights</Name> @@ -273,6 +281,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Dialogs\ExportToCsvDialogView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Themes\Generic.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -323,6 +335,9 @@ <ItemGroup> <Resource Include="Images\update_package.png" /> </ItemGroup> + <ItemGroup> + <Resource Include="Images\excel.png" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" /> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/ViewModels/InsightsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/ViewModels/InsightsViewVM.cs index 8f14534a3..af2060db8 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/ViewModels/InsightsViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/ViewModels/InsightsViewVM.cs @@ -19,6 +19,7 @@ using System.Windows.Media; using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.Core.Commands; +using Tango.CSV; using Tango.FSE.Common; using Tango.FSE.Common.Dialogs; using Tango.FSE.Common.Insights; @@ -177,7 +178,6 @@ namespace Tango.FSE.Insights.ViewModels set { _isDetecting = value; RaisePropertyChangedAuto(); } } - public AnnotationCollection Annotations { get; set; } #endregion @@ -194,6 +194,8 @@ namespace Tango.FSE.Insights.ViewModels public RelayCommand AnalyzeCommand { get; set; } + public RelayCommand ExportToCsvCommand { get; set; } + #endregion #region Constructors @@ -204,11 +206,11 @@ namespace Tango.FSE.Insights.ViewModels { MinDate = DateTime.Now.AddDays(-30); } - MaxDate = DateTime.Now; + MaxDate = DateTime.Now; IsSearchBarOpened = true; - DisplayAnnotations = true; - DisplayAnomalies = true; + DisplayAnnotations = false; + DisplayAnomalies = false; Charts = new ObservableCollection<InsightsChart>(); VisibleCharts = new ObservableCollection<InsightsChart>(); Annotations = new AnnotationCollection(); @@ -218,6 +220,7 @@ namespace Tango.FSE.Insights.ViewModels OpenBugReportCommand = new RelayCommand<InsightsReadyBug>(OpenAnnotationBugReport); ViewApplicationExceptionCommand = new RelayCommand<InsightsReadyApplicationException>(ViewAnnotationApplicationException); AnalyzeCommand = new RelayCommand(Analyze, () => InsightsPackage != null); + ExportToCsvCommand = new RelayCommand(ExportToCsv, () => InsightsPackage != null); } #endregion @@ -732,6 +735,7 @@ namespace Tango.FSE.Insights.ViewModels }); View.ZoomExtents(); + DisplayAnomalies = true; } catch (Exception ex) { @@ -749,6 +753,75 @@ namespace Tango.FSE.Insights.ViewModels #endregion + #region Export CSV + + private async void ExportToCsv() + { + var vm = await NotificationProvider.ShowDialog(new ExportToCsvDialogViewVM(Charts.ToList(), VisibleCharts.ToList())); + if (!vm.DialogResult) return; + + var snackbar = NotificationProvider.PushProgressSnackbar("Exporting insights", "Exporting insights to csv..."); + + try + { + await Task.Factory.StartNew(() => + { + List<InsightsChart> chartsToExport = vm.SelectedCharts.SynchedSource.ToList(); + + List<Func<InsightsMonitors, double>> delegates = new List<Func<InsightsMonitors, double>>(); + + foreach (var chart in chartsToExport) + { + var del = + Delegate.CreateDelegate(typeof(Func<InsightsMonitors, double>), + chart.InsightsMonitorsProperty.GetGetMethod()) + as Func<InsightsMonitors, double>; + + delegates.Add(del); + } + + using (DynamicCsvFile csvFile = new DynamicCsvFile(vm.SelectedFile)) + { + csvFile.Columns = chartsToExport.Select(x => new DynamicCsvFileColumn() { Name = x.Description }).ToList(); + csvFile.Columns.Insert(0, new DynamicCsvFileColumn() { Name = "Time" }); + + int progress = 0; + + foreach (var frame in InsightsPackage.Frames) + { + List<String> values = new List<string>(); + values.Add(frame.Frame.Time.ToLocalTime().ToString("MM/dd/yyyy HH:mm:ss.fff")); + + foreach (var del in delegates) + { + double value = del(frame.Monitors); + String str = double.IsNaN(value) ? String.Empty : value.ToString(); + values.Add(str); + } + + csvFile.Append<String>(values); + + progress++; + + snackbar.Message = $"Exporting insights to csv ({(int)((double)progress / (double)InsightsPackage.Frames.Count * 100d)})..."; + } + } + + snackbar.ProgressCompleted("File exported successfully.\nTap here to view the file.", TimeSpan.FromSeconds(10), () => + { + StorageProvider.ShowInExplorer(vm.SelectedFile); + }); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting insights csv file."); + snackbar.ProgressFailed($"Error exporting csv file.\n{ex.Message}"); + } + } + + #endregion + #region Private Methods private void OnMonitorsFilterChanged() diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Views/InsightsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Views/InsightsView.xaml index 844e2adee..a0df61d5b 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Views/InsightsView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Insights/Views/InsightsView.xaml @@ -241,18 +241,21 @@ </MenuItem> </Menu> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center" Margin="5 20 5 5"> - <ToggleButton material:ToggleButtonAssist.SwitchTrackOnBackground="{StaticResource FSE_GreenBrush}" IsChecked="{Binding DisplayAnnotations}" Width="32" Height="32" Style="{StaticResource FSE_Toolbar_ToggleButton}" ToolTip="Display Annotations"> - <material:PackIcon Kind="MagnifyScan" /> + <ToggleButton material:ToggleButtonAssist.SwitchTrackOnBackground="{StaticResource FSE_YellowBrush}" IsChecked="{Binding DisplayAnnotations}" Width="32" Height="32" Style="{StaticResource FSE_Toolbar_ToggleButton}" ToolTip="Display Annotations"> + <material:PackIcon Kind="Lightbulb" /> </ToggleButton> <ToggleButton material:ToggleButtonAssist.SwitchTrackOnBackground="{StaticResource FSE_RedBrush}" Margin="5 0 0 0" IsChecked="{Binding DisplayAnomalies}" Width="32" Height="32" Style="{StaticResource FSE_Toolbar_ToggleButton}" ToolTip="Display Anomalies"> <material:PackIcon Kind="Spider" /> </ToggleButton> - <Button Cursor="Hand" Command="{Binding AnalyzeCommand}" Margin="10 0 0 0" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" material:ButtonAssist.CornerRadius="3" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" BorderBrush="{StaticResource FSE_RedBrush}" BorderThickness="1"> + <Button Cursor="Hand" Command="{Binding AnalyzeCommand}" Margin="5 0 0 0" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" material:ButtonAssist.CornerRadius="3" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" BorderBrush="{StaticResource FSE_RedBrush}" BorderThickness="1"> <DockPanel> <material:PackIcon VerticalAlignment="Center" Kind="Spider" Foreground="{StaticResource FSE_RedBrush}" /> <TextBlock Margin="10 0 0 0">Detect Anomalies</TextBlock> </DockPanel> </Button> + <Button ToolTip="Export Monitors Data To CSV" Margin="10 0 0 0" BorderBrush="{StaticResource FSE_GreenBrush}" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" Width="32" Padding="0" FocusVisualStyle="{x:Null}" material:ButtonAssist.CornerRadius="3" Command="{Binding ExportToCsvCommand}"> + <material:PackIcon Kind="FileExcelOutline" Foreground="{StaticResource FSE_GreenBrush}" Width="18" Height="18" /> + </Button> </StackPanel> <Grid DockPanel.Dock="Top" Width="330" Margin="0 10 0 0" HorizontalAlignment="Center"> <Polygon Stroke="{StaticResource FSE_PrimaryAccentBrush}" StrokeThickness="1" Stretch="Fill" Height="50" Points="0,15 15,0 285,0 300,15 285,30 15,30"></Polygon> diff --git a/Software/Visual_Studio/Tango.CSV/DynamicCsvFile.cs b/Software/Visual_Studio/Tango.CSV/DynamicCsvFile.cs new file mode 100644 index 000000000..0c4d79949 --- /dev/null +++ b/Software/Visual_Studio/Tango.CSV/DynamicCsvFile.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.CSV +{ + public class DynamicCsvFile : IDisposable + { + private bool _isDisposed; + private Stream _stream; + private StreamWriter _writer; + private bool _disposeStream; + private bool _columnsWritten; + + public List<DynamicCsvFileColumn> Columns { get; set; } + + public DynamicCsvFile() + { + Columns = new List<DynamicCsvFileColumn>(); + } + + public DynamicCsvFile(Stream stream) : this() + { + _stream = stream; + _writer = new StreamWriter(_stream); + } + + public DynamicCsvFile(String file) : this(new FileStream(file, FileMode.Create)) + { + _disposeStream = true; + } + + private void WriteColumns() + { + if (!_columnsWritten) + { + _columnsWritten = true; + _writer.WriteLine(String.Join(",", Columns.Select(x => x.Name))); + } + } + + public void Append(params Object[] values) + { + Append((IEnumerable)values); + } + + public void Append<T>(IEnumerable<T> values, Func<T, Object> modifier = null) + { + if (modifier != null) + { + Append((IEnumerable)values, (x) => { return modifier((T)x); }); + } + else + { + Append((IEnumerable)values, null); + } + } + + public void Append(IEnumerable values, Func<Object, Object> modifier = null) + { + if (!_columnsWritten) + { + WriteColumns(); + } + + List<String> valuesStr = new List<string>(); + + foreach (var value in values) + { + Object finalValue = value; + + if (modifier != null) + { + finalValue = modifier(finalValue); + } + + valuesStr.Add(finalValue != null ? finalValue.ToString() : String.Empty); + } + + _writer.WriteLine(String.Join(",", valuesStr)); + } + + public void Dispose() + { + if (!_isDisposed) + { + _isDisposed = true; + + if (_disposeStream) + { + _stream?.Dispose(); + } + } + } + } +} diff --git a/Software/Visual_Studio/Tango.CSV/DynamicCsvFileColumn.cs b/Software/Visual_Studio/Tango.CSV/DynamicCsvFileColumn.cs new file mode 100644 index 000000000..c8fd850e7 --- /dev/null +++ b/Software/Visual_Studio/Tango.CSV/DynamicCsvFileColumn.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.CSV +{ + public class DynamicCsvFileColumn + { + public String Name { get; set; } + } +} diff --git a/Software/Visual_Studio/Tango.CSV/Tango.CSV.csproj b/Software/Visual_Studio/Tango.CSV/Tango.CSV.csproj index c3e455ff1..b6743bede 100644 --- a/Software/Visual_Studio/Tango.CSV/Tango.CSV.csproj +++ b/Software/Visual_Studio/Tango.CSV/Tango.CSV.csproj @@ -87,6 +87,8 @@ <Compile Include="CsvIgnoreAttribute.cs" /> <Compile Include="CsvOrderAttribute.cs" /> <Compile Include="CsvSource.cs" /> + <Compile Include="DynamicCsvFile.cs" /> + <Compile Include="DynamicCsvFileColumn.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
