aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2018-02-18 18:48:16 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2018-02-18 18:48:16 +0200
commit95b4e14bc4e06ffb94199f5ec4e0d2d9bebceeff (patch)
treede29ed87bd7c7b966d35b6f6bc8b13d65313c88c /Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer
parent99136fc92c8b75c3783f543051c065c28961d393 (diff)
downloadTango-95b4e14bc4e06ffb94199f5ec4e0d2d9bebceeff.tar.gz
Tango-95b4e14bc4e06ffb94199f5ec4e0d2d9bebceeff.zip
Working on new developer module.
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj3
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs151
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml13
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml13
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/packages.config1
5 files changed, 155 insertions, 26 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj
index 086d6cd91..eae234a8b 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj
@@ -31,6 +31,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="DeepEqual, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DeepEqual.1.6.0.0\lib\net40\DeepEqual.dll</HintPath>
+ </Reference>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
index 7a1c94504..5c5531063 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
@@ -34,6 +34,8 @@ using Tango.MachineStudio.Common.Video;
using Tango.Integration.Services;
using Tango.MachineStudio.Developer.Navigation;
using System.Data.Entity;
+using Tango.MachineStudio.Common.Authentication;
+using DeepEqual.Syntax;
namespace Tango.MachineStudio.Developer.ViewModels
{
@@ -52,18 +54,24 @@ namespace Tango.MachineStudio.Developer.ViewModels
private ObservablesContext _dbJobContext;
private Job _jobFromList;
private bool _blockInvalidateCommands;
+ private IAuthenticationProvider _authentication;
#region Properties
private ObservableCollection<ColorSpace> _colorSpaces;
-
+ /// <summary>
+ /// Gets or sets the color spaces.
+ /// </summary>
public ObservableCollection<ColorSpace> ColorSpaces
{
get { return _colorSpaces; }
set { _colorSpaces = value; RaisePropertyChangedAuto(); }
}
- private ObservableCollection<Rml> _rmls;
+ private ObservableCollection<Rml> _rmls;
+ /// <summary>
+ /// Gets or sets the RMLS.
+ /// </summary>
public ObservableCollection<Rml> Rmls
{
get { return _rmls; }
@@ -172,6 +180,16 @@ namespace Tango.MachineStudio.Developer.ViewModels
}
}
+ private ObservableCollection<Job> _selectedJobs;
+ /// <summary>
+ /// Gets or sets the selected jobs.
+ /// </summary>
+ public ObservableCollection<Job> SelectedJobs
+ {
+ get { return _selectedJobs; }
+ set { _selectedJobs = value; RaisePropertyChangedAuto(); }
+ }
+
private Segment _selectedSegment;
/// <summary>
/// Gets or sets the job selected segment.
@@ -182,6 +200,16 @@ namespace Tango.MachineStudio.Developer.ViewModels
set { _selectedSegment = value; RaisePropertyChangedAuto(); OnSelectedSegmentChanged(); }
}
+ private ObservableCollection<Segment> _selectedSegments;
+ /// <summary>
+ /// Gets or sets the selected segments.
+ /// </summary>
+ public ObservableCollection<Segment> SelectedSegments
+ {
+ get { return _selectedSegments; }
+ set { _selectedSegments = value; RaisePropertyChangedAuto(); }
+ }
+
private BrushStop _selectedBrushStop;
/// <summary>
/// Gets or sets the selected segment selected brush stop.
@@ -192,6 +220,16 @@ namespace Tango.MachineStudio.Developer.ViewModels
set { _selectedBrushStop = value; RaisePropertyChangedAuto(); }
}
+ private ObservableCollection<BrushStop> _selectedBrushStops;
+ /// <summary>
+ /// Gets or sets the selected brush stops.
+ /// </summary>
+ public ObservableCollection<BrushStop> SelectedBrushStops
+ {
+ get { return _selectedBrushStops; }
+ set { _selectedBrushStops = value; RaisePropertyChangedAuto(); }
+ }
+
private Rml _selectedRML;
/// <summary>
/// Gets or sets the selected RML.
@@ -457,6 +495,11 @@ namespace Tango.MachineStudio.Developer.ViewModels
/// </summary>
public RelayCommand LoadJobCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the duplicate job command.
+ /// </summary>
+ public RelayCommand DuplicateJobCommand { get; set; }
+
#endregion
#region Constructors
@@ -482,8 +525,12 @@ namespace Tango.MachineStudio.Developer.ViewModels
/// <param name="applicationManager">The application manager.</param>
/// <param name="notificationProvider">The notification provider.</param>
[PreferredConstructor]
- public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IMainView view, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation) : this(view)
+ public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IMainView view, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, IAuthenticationProvider authentication) : this(view)
{
+ SelectedJobs = new ObservableCollection<Job>();
+
+ _authentication = authentication;
+
_notification = notificationProvider;
_navigation = navigation;
ApplicationManager = applicationManager;
@@ -509,6 +556,7 @@ namespace Tango.MachineStudio.Developer.ViewModels
CloseJobCompletionStatusCommand = new RelayCommand(CloseJobCompletionStatusBar);
ExitFullScreenCommand = new RelayCommand(ExitFullScreen);
LoadJobCommand = new RelayCommand(LoadJob, () => SelectedJob != null);
+ DuplicateJobCommand = new RelayCommand(DuplicateJob, () => SelectedJob != null);
ToggleCameraCommand = new RelayCommand<CaptureDevice>(ToggleCamera);
@@ -547,6 +595,7 @@ namespace Tango.MachineStudio.Developer.ViewModels
private void SelectedMachine_Saved(object sender, EventArgs e)
{
InvalidateLiquidFactorsAndProcessTables();
+ SelectedMachine.Reload();
}
/// <summary>
@@ -640,14 +689,43 @@ namespace Tango.MachineStudio.Developer.ViewModels
#region Private Methods
+ private async void DuplicateJob()
+ {
+ if (SelectedJobs.Count > 0)
+ {
+ using (_notification.PushTaskItem("Cloning selected jobs..."))
+ {
+ int index = SelectedMachine.Jobs.Max(x => x.JobIndex);
+
+ foreach (var job in SelectedJobs)
+ {
+ var cloned = job.Clone();
+ cloned.JobIndex = ++index;
+ SelectedMachine.Jobs.Add(cloned);
+ }
+
+ await SelectedMachine.SaveAsync();
+ }
+ }
+ }
+
private async void LoadJob()
{
if (SelectedJob != null)
{
+ SelectedSegments = new ObservableCollection<Segment>();
+ SelectedBrushStops = new ObservableCollection<BrushStop>();
+ SelectedRML = null;
+ SelectedSegment = null;
+ SelectedGroupHistory = null;
+ SelectedBrushStop = null;
+ SelectedProcessParametersTable = null;
+ RmlProcessParametersTableGroup = null;
+
using (_notification.PushTaskItem("Loading job details..."))
{
- await Task.Factory.StartNew(() =>
- {
+ //await Task.Factory.StartNew(() =>
+ //{
_blockInvalidateCommands = false;
_dbJobContext = ObservablesContext.CreateDefault();
@@ -675,7 +753,7 @@ namespace Tango.MachineStudio.Developer.ViewModels
InvalidateRelayCommands();
InvokeUI(() => _navigation.NavigateTo(DeveloperNavigationView.JobView));
- });
+ //});
}
}
}
@@ -688,15 +766,45 @@ namespace Tango.MachineStudio.Developer.ViewModels
{
SelectedJob.LastUpdated = DateTime.UtcNow;
SelectedJob.Rml = SelectedRML;
- await SelectedJob.SaveAsync();
+ await SelectedJob.SaveAsync(_dbJobContext);
+ _jobFromList = SelectedMachine.Jobs.SingleOrDefault(x => x.Guid == SelectedJob.Guid);
await _jobFromList.Reload();
+
+ foreach (var segment in _jobFromList.Segments)
+ {
+ await segment.Reload();
+
+ foreach (var stop in segment.BrushStops)
+ {
+ await stop.Reload();
+ }
+ }
}
}
}
private void DiscardJob()
{
- if (_notification.ShowQuestion("This will discard the current job changes. Are you sue?"))
+ //bool jobModified = !SelectedJob.WithDeepEqual(_jobFromList)
+ // .IgnoreSourceProperty(x => x.Machine)
+ // .IgnoreSourceProperty(x => x.JobRuns)
+ // .IgnoreSourceProperty(x => x.Parameters)
+ // .IgnoreSourceProperty(x => x.Rml)
+ // .IgnoreSourceProperty(x => x.User)
+ // .IgnoreSourceProperty(x => x.Segments)
+ // .Compare();
+
+ bool jobModified = !SelectedJob.CompareUsingJson(_jobFromList);
+
+ if (jobModified)
+ {
+ if (_notification.ShowQuestion("This will discard the current job changes. Are you sue?"))
+ {
+ _dbJobContext.Dispose();
+ _navigation.NavigateTo(DeveloperNavigationView.MachineJobSelectionView);
+ }
+ }
+ else
{
_dbJobContext.Dispose();
_navigation.NavigateTo(DeveloperNavigationView.MachineJobSelectionView);
@@ -1012,11 +1120,18 @@ namespace Tango.MachineStudio.Developer.ViewModels
/// <summary>
/// Removes the selected job.
/// </summary>
- private void RemoveJob()
+ private async void RemoveJob()
{
if (SelectedMachine != null && SelectedJob != null)
{
- SelectedMachine.Jobs.Remove(SelectedJob);
+ if (_notification.ShowQuestion("Are you sure you want to delete the selected jobs?"))
+ {
+ SelectedJobs.ToList().ForEach(x =>
+ {
+ x.DefferedDelete();
+ });
+ await SelectedMachine.SaveAsync();
+ }
}
}
@@ -1027,11 +1142,19 @@ namespace Tango.MachineStudio.Developer.ViewModels
{
if (SelectedMachine != null)
{
- SelectedMachine.Jobs.Add(new Job(DateTime.UtcNow)
+ String jobName = _notification.ShowTextInput("Please provide a job name", "Name");
+
+ if (!String.IsNullOrWhiteSpace(jobName))
{
- Name = "Untitled Job",
- CreationDate = DateTime.UtcNow,
- });
+ Job newJob = new Job();
+ newJob.Name = jobName;
+ newJob.CreationDate = DateTime.UtcNow;
+ newJob.User = _authentication.CurrentUser;
+ newJob.Rml = Adapter.Rmls.FirstOrDefault();
+
+ SelectedJob = newJob;
+ LoadJob();
+ }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml
index b6455175e..35a30e91e 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml
@@ -14,6 +14,7 @@
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:db="clr-namespace:Tango.MachineStudio.DB.Views.DBViews;assembly=Tango.MachineStudio.DB"
xmlns:commonControls="clr-namespace:Tango.MachineStudio.Common.Controls;assembly=Tango.MachineStudio.Common"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
xmlns:designer="clr-namespace:Tango.MachineStudio.MachineDesigner.Views;assembly=Tango.MachineStudio.MachineDesigner"
xmlns:vm="clr-namespace:Tango.MachineStudio.Developer.ViewModels"
xmlns:localConverters="clr-namespace:Tango.MachineStudio.Developer.Converters"
@@ -230,7 +231,7 @@
<Grid Background="#96FFFFFF">
<Grid.Style>
<Style TargetType="Grid">
- <Setter Property="Width" Value="300"></Setter>
+ <Setter Property="Width" Value="304"></Setter>
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform ScaleY="1" ScaleX="1"></ScaleTransform>
@@ -280,7 +281,7 @@
</StackPanel>
</Border>
- <ListBox SelectionMode="Extended" SelectionChanged="ListBox_SelectionChanged" ItemsSource="{Binding SelectedJob.Segments}" SelectedItem="{Binding SelectedSegment}" HorizontalContentAlignment="Stretch">
+ <controls:MultiSelectListBox Style="{StaticResource {x:Type ListBox}}" SelectionMode="Extended" SelectionChanged="ListBox_SelectionChanged" ItemsSource="{Binding SelectedJob.Segments}" SelectedItem="{Binding SelectedSegment}" SelectedItemsList="{Binding SelectedSegments,Mode=TwoWay}" HorizontalContentAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource basicListBoxItem}">
@@ -345,7 +346,7 @@
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
- </ListBox>
+ </controls:MultiSelectListBox>
</DockPanel>
<Rectangle HorizontalAlignment="Right" StrokeThickness="1" Width="3" Margin="0 0 0 0">
@@ -618,7 +619,7 @@
</Rectangle>
</Grid>
<Grid Margin="0 10 10 0">
- <ListBox SelectionMode="Extended" Style="{x:Null}" Background="Transparent" ScrollViewer.CanContentScroll="False" BorderThickness="0" ItemsSource="{Binding SelectedSegment.BrushStops}" SelectedItem="{Binding SelectedBrushStop}" HorizontalContentAlignment="Stretch">
+ <controls:MultiSelectListBox SelectionMode="Extended" Style="{x:Null}" Background="Transparent" ScrollViewer.CanContentScroll="False" BorderThickness="0" ItemsSource="{Binding SelectedSegment.BrushStops}" SelectedItem="{Binding SelectedBrushStop}" SelectedItemsList="{Binding SelectedBrushStops,Mode=TwoWay}" HorizontalContentAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource basicListBoxItem}">
@@ -810,7 +811,7 @@
<Image Source="../Images/colorspace.png" Width="24"></Image>
<TextBlock VerticalAlignment="Center" Margin="5 0 0 0" FontSize="10">Color Space</TextBlock>
</StackPanel>
- <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ColorSpaces}" SelectedItem="{Binding ColorSpace}" DisplayMemberPath="Name">
+ <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ColorSpaces}" SelectedItem="{Binding ColorSpace}" DisplayMemberPath="Name" Width="100" HorizontalAlignment="Left">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Setter Property="Background" Value="#ECECEC"></Setter>
@@ -1052,7 +1053,7 @@
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
- </ListBox>
+ </controls:MultiSelectListBox>
</Grid>
</DockPanel>
</Grid>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml
index 998ba474d..b8d423026 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml
@@ -8,6 +8,7 @@
xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:localConverters="clr-namespace:Tango.MachineStudio.Developer.Converters"
xmlns:vm="clr-namespace:Tango.MachineStudio.Developer.ViewModels"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
xmlns:observables="clr-namespace:Tango.Integration.Observables;assembly=Tango.Integration"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -85,19 +86,19 @@
<Grid DockPanel.Dock="Bottom">
<StackPanel VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Left" Margin="20 0 0 0">
- <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="#FF7575" BorderBrush="#FF7575">
+ <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="#FF7575" BorderBrush="#FF7575" Command="{Binding RemoveJobCommand}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Delete" Width="20" Height="20" />
<TextBlock Margin="5 0 0 0" FontSize="16">DELETE</TextBlock>
</StackPanel>
</Button>
- <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="#FF995A" BorderBrush="#FF995A">
+ <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="#FF995A" BorderBrush="#FF995A" Command="{Binding DuplicateJobCommand}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="ContentCopy" Width="20" Height="20" />
<TextBlock Margin="5 0 0 0" FontSize="16">DUPLICATE</TextBlock>
</StackPanel>
</Button>
- <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="#65C682" BorderBrush="#65C682">
+ <Button Margin="0 0 10 0" MinWidth="160" Height="50" Background="#65C682" BorderBrush="#65C682" Command="{Binding AddJobCommand}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Plus" Width="20" Height="20" />
<TextBlock Margin="5 0 0 0" FontSize="16">NEW JOB</TextBlock>
@@ -115,7 +116,7 @@
</Grid>
<Grid Margin="0 20 0 0">
- <DataGrid CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" AutoGenerateColumns="False" Background="Transparent" ItemsSource="{Binding SelectedMachine.Jobs}" SelectedItem="{Binding SelectedJob}">
+ <controls:MultiSelectDataGrid Style="{StaticResource {x:Type DataGrid}}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" AutoGenerateColumns="False" Background="Transparent" ItemsSource="{Binding SelectedMachine.Jobs}" SelectedItem="{Binding SelectedJob}" SelectedItemsList="{Binding SelectedJobs,Mode=TwoWay}">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="BorderThickness" Value="0"/>
@@ -145,7 +146,7 @@
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
- <DataGridTemplateColumn Header="LAST MODIFIED" Width="185" CanUserSort="True" SortMemberPath="CreationDate">
+ <DataGridTemplateColumn Header="LAST MODIFIED" Width="185" CanUserSort="True" SortMemberPath="LastUpdated">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding LastUpdated,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" VerticalAlignment="Center" FontSize="16"></TextBlock>
@@ -192,7 +193,7 @@
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
- </DataGrid>
+ </controls:MultiSelectDataGrid>
</Grid>
</DockPanel>
</Grid>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/packages.config
index 7994d1504..c3235a090 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/packages.config
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/packages.config
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommonServiceLocator" version="1.3" targetFramework="net46" />
+ <package id="DeepEqual" version="1.6.0.0" targetFramework="net46" />
<package id="EntityFramework" version="6.0.0" targetFramework="net46" />
<package id="Google.Protobuf" version="3.4.1" targetFramework="net46" />
<package id="MahApps.Metro" version="1.5.0" targetFramework="net46" />