Init commit

This commit is contained in:
NickAppLab
2022-06-13 21:24:13 +05:00
commit 60eb406cbe
42 changed files with 3806 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*\obj
*\bin
*\packages

6
App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

9
App.xaml Normal file
View File

@@ -0,0 +1,9 @@
<Application x:Class="StructureHelper.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StructureHelper"
StartupUri="Windows/MainWindow/MainView.xaml">
<Application.Resources>
</Application.Resources>
</Application>

11
App.xaml.cs Normal file
View File

@@ -0,0 +1,11 @@
using System.Windows;
namespace StructureHelper
{
/// <summary>
/// Логика взаимодействия для App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,13 @@
using System;
namespace StructureHelper
{
public class EventArgs<T> : EventArgs
{
public EventArgs(T value)
{
Value = value;
}
public T Value { get; private set; }
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Windows;
using EventTrigger = System.Windows.Interactivity.EventTrigger;
namespace StructureHelper
{
public class EventTriggerBase<T> : EventTrigger where T : RoutedEventArgs
{
readonly Predicate<T> eventTriggerPredicate;
public EventTriggerBase(Predicate<T> eventTriggerPredicate)
{
this.eventTriggerPredicate = eventTriggerPredicate;
}
protected override void OnEvent(EventArgs eventArgs)
{
if (eventArgs is T e && eventTriggerPredicate(e))
{
base.OnEvent(eventArgs);
e.Handled = true;
}
}
}
}

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace StructureHelper
{
public static class ObservableCollectionExtensions
{
public static void MoveElementToEnd<T>(this ObservableCollection<T> collection, T element)
{
var elementCopy = element;
collection.Remove(element);
collection.Add(elementCopy);
}
public static void MoveElementToBegin<T>(this ObservableCollection<T> collection, T element)
{
var collectionCopy = new List<T>(collection);
collectionCopy.Remove(element);
collection.Clear();
collection.Add(element);
foreach (var collectionElem in collectionCopy)
collection.Add(collectionElem);
}
public static void MoveElementToSelectedIndex<T>(this ObservableCollection<T> collection, T element, int index)
{
collection.Remove(element);
collection.Insert(index - 1, element);
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace StructureHelper
{
public class MouseBehaviour : Behavior<Panel>
{
public static readonly DependencyProperty MouseYProperty = DependencyProperty.Register(
"MouseY", typeof(double), typeof(MouseBehaviour), new PropertyMetadata(default(double)));
public static readonly DependencyProperty MouseXProperty = DependencyProperty.Register(
"MouseX", typeof(double), typeof(MouseBehaviour), new PropertyMetadata(default(double)));
public double MouseY
{
get => (double)GetValue(MouseYProperty);
set => SetValue(MouseYProperty, value);
}
public double MouseX
{
get => (double)GetValue(MouseXProperty);
set => SetValue(MouseXProperty, value);
}
protected override void OnAttached()
{
AssociatedObject.MouseMove += AssociatedObjectOnMouseMove;
}
protected override void OnDetaching()
{
AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove;
}
private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
var pos = mouseEventArgs.GetPosition(AssociatedObject);
MouseX = pos.X;
MouseY = pos.Y;
}
}
}

View File

@@ -0,0 +1,9 @@
using System.Windows.Input;
namespace StructureHelper.Infrastructure
{
public class DoubleClickEventTrigger : EventTriggerBase<MouseButtonEventArgs>
{
public DoubleClickEventTrigger() : base(args => args.ClickCount == 2) { }
}
}

View File

@@ -0,0 +1,9 @@
using System.Windows.Input;
namespace StructureHelper.Infrastructure
{
public class MouseWheelDownEventTrigger : EventTriggerBase<MouseWheelEventArgs>
{
public MouseWheelDownEventTrigger() : base(args => args.Delta > 0) { }
}
}

View File

@@ -0,0 +1,9 @@
using System.Windows.Input;
namespace StructureHelper.Infrastructure
{
public class MouseWheelUpEventTrigger : EventTriggerBase<MouseWheelEventArgs>
{
public MouseWheelUpEventTrigger() : base(args => args.Delta < 0) { }
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace StructureHelper.Infrastructure
{
public class NamedList<T> : List<T>
{
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Windows.Input;
namespace StructureHelper
{
public class RelayCommand : ICommand
{
private Action<object> execute;
private Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter) => canExecute == null || canExecute(parameter);
public void Execute(object parameter) => execute(parameter);
}
}

View File

@@ -0,0 +1,27 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using StructureHelper.Annotations;
namespace StructureHelper.Infrastructure
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged<T>(T value, T prop, [CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged<T>(T value, ref T prop, [CallerMemberName] string propertyName = null)
{
prop = value;
OnPropertyChanged(propertyName);
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View File

@@ -0,0 +1,58 @@
using System.Collections.Generic;
using StructureHelper.Infrastructure;
namespace StructureHelper
{
public class MaterialCatalogModel
{
public NamedList<MaterialDefinitionBase> ConcreteDefinitions;
public NamedList<MaterialDefinitionBase> RebarDefinitions;
public List<NamedList<MaterialDefinitionBase>> Materials;
public MaterialCatalogModel()
{
InitializeMaterialCollections();
Materials = new List<NamedList<MaterialDefinitionBase>>();
Materials.Add(ConcreteDefinitions);
Materials.Add(RebarDefinitions);
}
public void InitializeMaterialCollections()
{
InitializeConcreteDefinitions();
InitializeRebarDefinitions();
}
private void InitializeRebarDefinitions()
{
RebarDefinitions = new NamedList<MaterialDefinitionBase>()
{
new RebarDefinition("S240", 2, 240, 240, 1.15, 1.15),
new RebarDefinition("S400", 2, 400, 400, 1.15, 1.15),
new RebarDefinition("S500", 2, 500, 500, 1.15, 1.15)
};
RebarDefinitions.Name = "Арматура";
}
private void InitializeConcreteDefinitions()
{
ConcreteDefinitions = new NamedList<MaterialDefinitionBase>()
{
new ConcreteDefinition("C10", 0, 10, 0, 1.3, 1.5),
new ConcreteDefinition("C15", 0, 15, 0, 1.3, 1.5),
new ConcreteDefinition("C20", 0, 20, 0, 1.3, 1.5),
new ConcreteDefinition("C25", 0, 25, 0, 1.3, 1.5),
new ConcreteDefinition("C30", 0, 30, 0, 1.3, 1.5),
new ConcreteDefinition("C35", 0, 35, 0, 1.3, 1.5),
new ConcreteDefinition("C40", 0, 40, 0, 1.3, 1.5),
new ConcreteDefinition("C45", 0, 45, 0, 1.3, 1.5),
new ConcreteDefinition("C50", 0, 50, 0, 1.3, 1.5),
new ConcreteDefinition("C60", 0, 60, 0, 1.3, 1.5),
new ConcreteDefinition("C70", 0, 70, 0, 1.3, 1.5),
new ConcreteDefinition("C80", 0, 80, 0, 1.3, 1.5)
};
ConcreteDefinitions.Name = "Бетон";
}
}
}

View File

@@ -0,0 +1,80 @@
<Window x:Class="StructureHelper.MaterialCatalogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:MaterialCatalogViewModel}"
Title="Справочник материалов" Height="900" Width="1100">
<Window.Resources>
<DataTemplate x:Key="RebarYoungModulusTemplate">
<StackPanel Orientation="Horizontal">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Text="{Binding YoungModulus}"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text=" x 10^11"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CompressiveStrengthTemplate">
<StackPanel Orientation="Horizontal">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Text="{Binding CompressiveStrength}"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text=" x 10^6"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="TensileStrengthTemplate">
<StackPanel Orientation="Horizontal">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Text="{Binding TensileStrength}"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text=" x 10^6"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="MaterialClassTemplate">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Text="{Binding MaterialClass}"/>
</DataTemplate>
<DataTemplate x:Key="MaterialCoefInCompressTemplate">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Text="{Binding MaterialCoefInCompress}"/>
</DataTemplate>
<DataTemplate x:Key="MaterialCoefInTensionTemplate">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Text="{Binding MaterialCoefInTension}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="10">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10,20,10,10" Text="Бетон" FontSize="16"/>
<DataGrid ItemsSource="{Binding ConcreteDefinitions}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedMaterial}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Класс" CellTemplate="{StaticResource MaterialClassTemplate}"/>
<DataGridTextColumn Header="Модуль упругости" Binding="{Binding YoungModulus, StringFormat={}{0} x 10^6}" IsReadOnly="True"/>
<DataGridTemplateColumn Header="Нормативная прочность на сжатие" CellTemplate="{StaticResource CompressiveStrengthTemplate}"/>
<DataGridTextColumn Header="Нормативная прочность на растяжение" Binding="{Binding TensileStrength, StringFormat={}{0} x 10^3}" IsReadOnly="True"/>
<DataGridTemplateColumn Header="Коэффициент надежности при сжатии" CellTemplate="{StaticResource MaterialCoefInCompressTemplate}"/>
<DataGridTemplateColumn Header="Коэффициент надежности при растяжении" CellTemplate="{StaticResource MaterialCoefInTensionTemplate}"/>
</DataGrid.Columns>
</DataGrid>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10,20,10,10" Text="Арматура" FontSize="16"/>
<DataGrid ItemsSource="{Binding RebarDefinitions}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedMaterial}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Класс" CellTemplate="{StaticResource MaterialClassTemplate}"/>
<DataGridTemplateColumn Header="Модуль упругости" CellTemplate="{StaticResource RebarYoungModulusTemplate}"/>
<DataGridTemplateColumn Header="Нормативная прочность на сжатие" CellTemplate="{StaticResource CompressiveStrengthTemplate}"/>
<DataGridTemplateColumn Header="Нормативная прочность на растяжение" CellTemplate="{StaticResource TensileStrengthTemplate}"/>
<DataGridTemplateColumn Header="Коэффициент надежности при сжатии" CellTemplate="{StaticResource MaterialCoefInCompressTemplate}"/>
<DataGridTemplateColumn Header="Коэффициент надежности при растяжении" CellTemplate="{StaticResource MaterialCoefInTensionTemplate}"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Content="Добавить материал" Margin="10" Command="{Binding AddMaterial}"/>
<Button Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Выбрать материал" Margin="10" Command="{Binding SelectMaterial}" Visibility="{Binding SelectMaterialButtonVisibility}"/>
<Button Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Left" Content="Сохранить справочник" Margin="10" Command="{Binding SaveCatalog}"/>
<Button Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Загрузить справочник" Margin="10" Command="{Binding LoadCatalog}"/>
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,18 @@
using System.Windows;
namespace StructureHelper
{
/// <summary>
/// Логика взаимодействия для MaterialCatalogView.xaml
/// </summary>
public partial class MaterialCatalogView : Window
{
public MaterialCatalogView(bool isMaterialCanBeSelected = false, PrimitiveDefinition primitive = null)
{
var materialCatalogModel = new MaterialCatalogModel();
var materialCatalogViewModel = new MaterialCatalogViewModel(materialCatalogModel, this, isMaterialCanBeSelected, primitive);
DataContext = materialCatalogViewModel;
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,117 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using Newtonsoft.Json;
using StructureHelper.Annotations;
using OpenFileDialog = System.Windows.Forms.OpenFileDialog;
using SaveFileDialog = System.Windows.Forms.SaveFileDialog;
namespace StructureHelper
{
[JsonObject(MemberSerialization.OptIn)]
public class MaterialCatalogViewModel : INotifyPropertyChanged
{
private MaterialCatalogModel materialCatalogModel;
private MaterialCatalogView materialCatalogView;
[JsonProperty]
public ObservableCollection<MaterialDefinitionBase> ConcreteDefinitions { get; set; }
[JsonProperty]
public ObservableCollection<MaterialDefinitionBase> RebarDefinitions { get; set; }
public ICommand AddMaterial { get; }
public ICommand SaveCatalog { get; }
public ICommand LoadCatalog { get; }
public ICommand SelectMaterial { get; }
private MaterialDefinitionBase selectedMaterial;
public MaterialDefinitionBase SelectedMaterial
{
get => selectedMaterial;
set
{
selectedMaterial = value;
OnPropertyChanged();
}
}
private bool isMaterialCanBeSelected;
public bool IsMaterialCanBeSelected
{
get => isMaterialCanBeSelected;
set
{
isMaterialCanBeSelected = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SelectMaterialButtonVisibility));
}
}
public Visibility SelectMaterialButtonVisibility => IsMaterialCanBeSelected ? Visibility.Visible : Visibility.Hidden;
public MaterialCatalogViewModel() { }
public MaterialCatalogViewModel(MaterialCatalogModel materialCatalogModel, MaterialCatalogView materialCatalogView, bool isMaterialCanBeSelected, PrimitiveDefinition primitive = null)
{
this.materialCatalogModel = materialCatalogModel;
this.materialCatalogView = materialCatalogView;
IsMaterialCanBeSelected = isMaterialCanBeSelected;
ConcreteDefinitions = new ObservableCollection<MaterialDefinitionBase>(materialCatalogModel.ConcreteDefinitions);
RebarDefinitions = new ObservableCollection<MaterialDefinitionBase>(materialCatalogModel.RebarDefinitions);
AddMaterial = new RelayCommand(o =>
{
AddMaterialView addMaterialView = new AddMaterialView(this.materialCatalogModel, this);
addMaterialView.ShowDialog();
OnPropertyChanged(nameof(ConcreteDefinitions));
OnPropertyChanged(nameof(RebarDefinitions));
});
SaveCatalog = new RelayCommand(o =>
{
string json = JsonConvert.SerializeObject(this, Formatting.Indented);
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.InitialDirectory = @"C:\";
saveDialog.Filter = "json files (*.json)|*.json|All files(*.*)|*.*";
string path = null;
if (saveDialog.ShowDialog() == DialogResult.OK)
{
path = saveDialog.FileName;
File.WriteAllText(path, json);
}
});
LoadCatalog = new RelayCommand(o =>
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = @"C:\";
openFileDialog.Filter = "json files (*.json)|*.json|All files(*.*)|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
var path = openFileDialog.FileName;
var content = File.ReadAllText(path);
var vm = JsonConvert.DeserializeObject<MaterialCatalogViewModel>(content);
ConcreteDefinitions = vm.ConcreteDefinitions;
OnPropertyChanged(nameof(ConcreteDefinitions));
RebarDefinitions = vm.RebarDefinitions;
OnPropertyChanged(nameof(RebarDefinitions));
}
});
SelectMaterial = new RelayCommand(o =>
{
if (primitive != null)
primitive.Material = SelectedMaterial;
});
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MaterialResistanceCalc
{
public class ConcreteDefinition : MaterialDefinition
{
public ConcreteDefinition(string materialClass, double youngModulus, double compressiveStrengthCoef, double tensileStrengthCoef, double materialCoefInCompress, double materialCoefInTension)
: base(materialClass, youngModulus, compressiveStrengthCoef, tensileStrengthCoef, materialCoefInCompress, materialCoefInTension)
{
CompressiveStrength = compressiveStrengthCoef * Math.Pow(10, 6);
TensileStrength = tensileStrengthCoef * Math.Sqrt(CompressiveStrength);
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MaterialResistanceCalc
{
public class MaterialDefinition
{
public string MaterialClass { get; set; }
public double YoungModulus { get; set; }
public double CompressiveStrength { get; set; }
public double TensileStrength { get; set; }
public double MaterialCoefInCompress { get; set; }
public double MaterialCoefInTension { get; set; }
public MaterialDefinition(string materialClass, double youngModulus, double compressiveStrengthCoef, double tensileStrengthCoef, double materialCoefInCompress, double materialCoefInTension)
{
MaterialClass = materialClass;
YoungModulus = youngModulus;
CompressiveStrength = compressiveStrengthCoef;
TensileStrength = tensileStrengthCoef;
MaterialCoefInCompress = materialCoefInCompress;
MaterialCoefInTension = materialCoefInTension;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MaterialResistanceCalc
{
public class RebarDefinition : MaterialDefinition
{
public RebarDefinition(string materialClass, double youngModulus, double compressiveStrengthCoef, double tensileStrengthCoef, double materialCoefInCompress, double materialCoefInTension) : base(materialClass, youngModulus, compressiveStrengthCoef, tensileStrengthCoef, materialCoefInCompress, materialCoefInTension)
{
YoungModulus = youngModulus * Math.Pow(10, 11);
CompressiveStrength = compressiveStrengthCoef * Math.Pow(10, 6);
TensileStrength = tensileStrengthCoef * Math.Pow(10, 6);
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace StructureHelper
{
public class ConcreteDefinition : MaterialDefinitionBase
{
public ConcreteDefinition(string materialClass, double youngModulus, double compressiveStrengthCoef, double tensileStrengthCoef, double materialCoefInCompress, double materialCoefInTension)
: base(materialClass, youngModulus, compressiveStrengthCoef, tensileStrengthCoef, materialCoefInCompress, materialCoefInTension)
{
CompressiveStrength = compressiveStrengthCoef/* * Math.Pow(10, 6)*/;
TensileStrength = Math.Round(620 * Math.Sqrt(CompressiveStrength), 2);
YoungModulus = Math.Round(4.7 * Math.Sqrt(DesignCompressiveStrength), 2);
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
namespace StructureHelper
{
public class MaterialDefinitionBase
{
public string MaterialClass { get; set; }
public double YoungModulus { get; set; }
public double CompressiveStrength { get; set; }
public double TensileStrength { get; set; }
public double MaterialCoefInCompress { get; set; }
public double MaterialCoefInTension { get; set; }
public double DesignCompressiveStrength { get; set; }
public double DesingTensileStrength { get; set; }
public MaterialDefinitionBase(string materialClass, double youngModulus, double compressiveStrengthCoef, double tensileStrengthCoef, double materialCoefInCompress, double materialCoefInTension)
{
MaterialClass = materialClass;
YoungModulus = youngModulus;
CompressiveStrength = compressiveStrengthCoef;
TensileStrength = tensileStrengthCoef;
MaterialCoefInCompress = materialCoefInCompress;
MaterialCoefInTension = materialCoefInTension;
DesignCompressiveStrength = compressiveStrengthCoef * Math.Pow(10, 6) * 1 / 1;
DesingTensileStrength = tensileStrengthCoef * Math.Pow(10, 3) * 1 / materialCoefInTension;
}
}
}

View File

@@ -0,0 +1,12 @@
namespace StructureHelper
{
public class RebarDefinition : MaterialDefinitionBase
{
public RebarDefinition(string materialClass, double youngModulus, double compressiveStrengthCoef, double tensileStrengthCoef, double materialCoefInCompress, double materialCoefInTension) : base(materialClass, youngModulus, compressiveStrengthCoef, tensileStrengthCoef, materialCoefInCompress, materialCoefInTension)
{
YoungModulus = youngModulus/* * Math.Pow(10, 11)*/;
CompressiveStrength = compressiveStrengthCoef/* * Math.Pow(10, 6)*/;
TensileStrength = tensileStrengthCoef/* * Math.Pow(10, 6)*/;
}
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.Windows.Media;
namespace StructureHelper
{
public class EllipseDefinition : PrimitiveDefinitionBase
{
private double diameter, showedDiameter, ellipseX, ellipseY;
public double Diameter
{
get => diameter;
set
{
diameter = value;
ShowedDiameter = Math.Round(value, 2);
OnPropertyChanged();
}
}
public double ShowedDiameter
{
get => showedDiameter;
set
{
showedDiameter = value;
OnPropertyChanged();
}
}
public double EllipseX
{
get => ellipseX;
set
{
ellipseX = value;
OnPropertyChanged();
}
}
public double EllipseY
{
get => ellipseY;
set
{
ellipseY = value;
OnPropertyChanged();
}
}
private double showedEllipseX, showedEllipseY;
private double initialEllipseX, initialEllipseY;
public double ShowedEllipseX
{
get => showedEllipseX;
set
{
showedEllipseX = value;
EllipseX = value + initialEllipseX - Diameter / 2;
OnPropertyChanged(nameof(EllipseX));
OnPropertyChanged();
}
}
public double ShowedEllipseY
{
get => showedEllipseY;
set
{
showedEllipseY = value;
EllipseY = -value + initialEllipseY - Diameter / 2;
OnPropertyChanged(nameof(ShowedEllipseY));
OnPropertyChanged();
}
}
private double square;
public double Square
{
get => square;
set
{
square = value;
Diameter = Math.Sqrt(4 * value / Math.PI);
OnPropertyChanged(nameof(Diameter));
OnPropertyChanged();
}
}
public EllipseDefinition(double square, double ellipseX, double ellipseY)
{
Square = square;
initialEllipseX = ellipseX;
initialEllipseY = ellipseY;
ShowedEllipseX = 0;
ShowedEllipseY = 0;
var randomR = new Random().Next(150, 255);
var randomG = new Random().Next(0, 255);
var randomB = new Random().Next(30, 130);
var color = Color.FromRgb((byte)randomR, (byte)randomG, (byte)randomB);
Brush = new SolidColorBrush(color);
}
}
}

View File

@@ -0,0 +1,146 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Media;
using StructureHelper.Annotations;
namespace StructureHelper
{
public class PrimitiveDefinitionBase : INotifyPropertyChanged
{
private bool captured, parameterCaptured, elementLock;
public bool Captured
{
set
{
captured = value;
OnPropertyChanged();
}
get => captured;
}
public bool ParameterCaptured
{
set
{
parameterCaptured = value;
OnPropertyChanged();
}
get => parameterCaptured;
}
public bool ElementLock
{
get => elementLock;
set
{
elementLock = value;
OnPropertyChanged();
}
}
private SolidColorBrush brush = null;
public SolidColorBrush Brush
{
get => brush;
set
{
brush = value;
OnPropertyChanged();
}
}
private MaterialDefinitionBase material = null;
public MaterialDefinitionBase Material
{
get => material;
set
{
material = value;
MaterialName = material.MaterialClass;
OnPropertyChanged();
OnPropertyChanged(nameof(MaterialName));
}
}
private string materialName = string.Empty;
public string MaterialName
{
get => materialName;
set
{
materialName = value;
OnPropertyChanged();
}
}
private bool paramsPanelVisibilty;
public bool ParamsPanelVisibilty
{
get => paramsPanelVisibilty;
set
{
paramsPanelVisibilty = value;
OnPropertyChanged();
}
}
private bool popupCanBeClosed = true;
public bool PopupCanBeClosed
{
get => popupCanBeClosed;
set
{
popupCanBeClosed = value;
OnPropertyChanged();
}
}
private double opacity = 1;
private double showedOpacity = 0;
public double ShowedOpacity
{
get => showedOpacity;
set
{
showedOpacity = value;
Opacity = (100 - value) / 100;
OnPropertyChanged(nameof(Opacity));
OnPropertyChanged();
}
}
public double Opacity
{
get => opacity;
set
{
opacity = value;
OnPropertyChanged();
}
}
private int showedZIndex = 1;
public int ShowedZIndex
{
get => showedZIndex;
set
{
showedZIndex = value;
ZIndex = value - 1;
OnPropertyChanged(nameof(ZIndex));
OnPropertyChanged();
}
}
private int zIndex;
public int ZIndex
{
get => zIndex;
set
{
zIndex = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Windows.Media;
namespace StructureHelper
{
public class RectangleDefinition : PrimitiveDefinitionBase
{
private bool borderCaptured = false;
private double rectX, rectY, borderWidth, borderHeight;
public bool BorderCaptured
{
set
{
borderCaptured = value;
OnPropertyChanged();
}
get => borderCaptured;
}
public double RectX
{
get => rectX;
set
{
rectX = value;
OnPropertyChanged();
}
}
public double RectY
{
get => rectY;
set
{
rectY = value;
OnPropertyChanged();
}
}
private double showedRectX, showedRectY;
private double initialRectX, initialRectY;
public double ShowedRectX
{
get => showedRectX;
set
{
showedRectX = value;
RectX = value + initialRectX;
OnPropertyChanged(nameof(RectX));
OnPropertyChanged();
}
}
public double ShowedRectY
{
get => showedRectY;
set
{
showedRectY = value;
RectY = -value + initialRectY - BorderHeight;
OnPropertyChanged(nameof(RectY));
OnPropertyChanged();
}
}
public double BorderWidth
{
get => borderWidth;
set
{
borderWidth = value;
OnPropertyChanged();
}
}
public double BorderHeight
{
get => borderHeight;
set
{
borderHeight = value;
OnPropertyChanged();
}
}
public RectangleDefinition(double borderWidth, double borderHeight, double rectX, double rectY)
{
BorderWidth = borderWidth;
BorderHeight = borderHeight;
initialRectX = rectX;
initialRectY = rectY;
ShowedRectX = 0;
ShowedRectY = 0;
var randomR = new Random().Next(150, 255);
var randomG = new Random().Next(0, 255);
var randomB = new Random().Next(30, 130);
var color = Color.FromRgb((byte)randomR, (byte)randomG, (byte)randomB);
Brush = new SolidColorBrush(color);
}
}
}

1603
Properties/Annotations.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// Общие сведения об этой сборке предоставляются следующим набором
// набор атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
// связанные со сборкой.
[assembly: AssemblyTitle("StructureHelper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("StructureHelper")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
// из модели COM, установите атрибут ComVisible для этого типа в значение true.
[assembly: ComVisible(false)]
//Чтобы начать создание локализуемых приложений, задайте
//<UICulture>CultureYouAreCodingWith</UICulture> в файле .csproj
//в <PropertyGroup>. Например, при использовании английского (США)
//в своих исходных файлах установите <UICulture> в en-US. Затем отмените преобразование в комментарий
//атрибута NeutralResourceLanguage ниже. Обновите "en-US" в
//строка внизу для обеспечения соответствия настройки UICulture в файле проекта.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //где расположены словари ресурсов по конкретным тематикам
//(используется, если ресурс не найден на странице,
// или в словарях ресурсов приложения)
ResourceDictionaryLocation.SourceAssembly //где расположен словарь универсальных ресурсов
//(используется, если ресурс не найден на странице,
// в приложении или в каких-либо словарях ресурсов для конкретной темы)
)]
// Сведения о версии для сборки включают четыре следующих значения:
//
// Основной номер версии
// Дополнительный номер версии
// Номер сборки
// Номер редакции
//
// Можно задать все значения или принять номера сборки и редакции по умолчанию
// используя "*", как показано ниже:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

133
StructureHelper.csproj Normal file
View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" 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>{BAD27E27-4444-4300-ADF8-E21042C0781D}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>StructureHelper</RootNamespace>
<AssemblyName>StructureHelper</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Expression.Interactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\System.Windows.Interactivity.WPF.2.0.20525\lib\net40\Microsoft.Expression.Interactions.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\System.Windows.Interactivity.WPF.2.0.20525\lib\net40\System.Windows.Interactivity.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Windows\AddMaterialWindow\AddMaterialView.xaml.cs">
<DependentUpon>AddMaterialView.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\AddMaterialWindow\AddMaterialViewModel.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Windows\ColorPickerWindow\ColorPickerView.xaml.cs">
<DependentUpon>ColorPickerView.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\ColorPickerWindow\ColorPickerViewModel.cs" />
<Compile Include="Infrastructure\Extensions\ObservableCollectionExtensions.cs" />
<Compile Include="Infrastructure\EventTriggerBase.cs" />
<Compile Include="Infrastructure\MouseEventTriggers\MouseWheelUpEventTrigger.cs" />
<Compile Include="Infrastructure\MouseEventTriggers\MouseWheelDownEventTrigger.cs" />
<Compile Include="Infrastructure\ViewModelBase.cs" />
<Compile Include="Models\MaterialDefinition\ConcreteDefinition.cs" />
<Compile Include="Infrastructure\NamedList.cs" />
<Compile Include="Models\MaterialDefinition\MaterialDefinitionBase.cs" />
<Compile Include="Models\PrimitiveDefinition\EllipseDefinition.cs" />
<Compile Include="Models\PrimitiveDefinition\PrimitiveDefinitionBase.cs" />
<Compile Include="Properties\Annotations.cs" />
<Compile Include="Models\MaterialDefinition\RebarDefinition.cs" />
<Compile Include="Models\PrimitiveDefinition\RectangleDefinition.cs" />
<Compile Include="Windows\MainWindow\MainModel.cs" />
<Compile Include="Windows\MainWindow\MainView.xaml.cs" />
<Compile Include="Windows\MainWindow\MainViewModel.cs" />
<Compile Include="Infrastructure\RelayCommand.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Infrastructure\MouseEventTriggers\DoubleClickEventTrigger.cs" />
<Compile Include="Infrastructure\EventArgs.cs" />
<Compile Include="MaterialCatalogWindow\MaterialCatalogModel.cs" />
<Compile Include="MaterialCatalogWindow\MaterialCatalogView.xaml.cs" />
<Compile Include="MaterialCatalogWindow\MaterialCatalogViewModel.cs" />
<Compile Include="Infrastructure\MouseBehaviour.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Page Include="Windows\AddMaterialWindow\AddMaterialView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Windows\ColorPickerWindow\ColorPickerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MaterialCatalogWindow\MaterialCatalogView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Windows\MainWindow\MainView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

25
StructureHelper.sln Normal file
View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32002.261
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StructureHelper", "StructureHelper.csproj", "{BAD27E27-4444-4300-ADF8-E21042C0781D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BAD27E27-4444-4300-ADF8-E21042C0781D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAD27E27-4444-4300-ADF8-E21042C0781D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAD27E27-4444-4300-ADF8-E21042C0781D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAD27E27-4444-4300-ADF8-E21042C0781D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A4F97ACA-7F64-4D3E-AB47-8EE61B5BAB9A}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,47 @@
<Window x:Class="StructureHelper.AddMaterialView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:AddMaterialViewModel}"
Title="Добавление материала" Height="350" Width="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="{Binding RowHeight}"/>
<RowDefinition Height="40"/>
<RowDefinition Height="{Binding RowHeight}"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Группа материалов"/>
<ComboBox Grid.Row="0" Grid.Column="1" Margin="10" ItemsSource="{Binding Materials}" DisplayMemberPath="Name" SelectedItem="{Binding MaterialCollection}"/>
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Класс"/>
<TextBox Grid.Row="1" Grid.Column="1" Margin="10" Text="{Binding MaterialClass}"/>
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Модуль упругости" IsEnabled="{Binding IsNotConcrete}"/>
<TextBox Grid.Row="2" Grid.Column="1" Margin="10" IsEnabled="{Binding IsNotConcrete}" Text="{Binding YoungModulus}"/>
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Нормативная прочность на сжатие"/>
<TextBox Grid.Row="3" Grid.Column="1" Margin="10" Text="{Binding CompressiveStrengthCoef}"/>
<TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Нормативная прочность на растяжение" IsEnabled="{Binding IsNotConcrete}"/>
<TextBox Grid.Row="4" Grid.Column="1" Margin="10" Text="{Binding TensileStrengthCoef}" IsEnabled="{Binding IsNotConcrete}"/>
<TextBlock Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Коэффициент надежности при сжатии"/>
<TextBox Grid.Row="5" Grid.Column="1" Margin="10" Text="{Binding MaterialCoefInCompress}"/>
<TextBlock Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Коэффициент надежности при расширении"/>
<TextBox Grid.Row="6" Grid.Column="1" Margin="10" Text="{Binding MaterialCoefInTension}"/>
</Grid>
<Button Grid.Row="1" Grid.Column="0" Margin="10" HorizontalAlignment="Left" Content="Добавить материал" Command="{Binding AddMaterial}"/>
</Grid>
</Window>

View File

@@ -0,0 +1,17 @@
using System.Windows;
namespace StructureHelper
{
/// <summary>
/// Логика взаимодействия для AddMaterialView.xaml
/// </summary>
public partial class AddMaterialView : Window
{
public AddMaterialView(MaterialCatalogModel model, MaterialCatalogViewModel materialCatalogViewModel)
{
var viewModel = new AddMaterialViewModel(model, this, materialCatalogViewModel);
DataContext = viewModel;
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,82 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using StructureHelper.Infrastructure;
namespace StructureHelper
{
public class AddMaterialViewModel : ViewModelBase
{
private MaterialCatalogModel model;
private AddMaterialView view;
private MaterialCatalogViewModel materialCatalogViewModel;
public ObservableCollection<NamedList<MaterialDefinitionBase>> Materials { get; set; }
private NamedList<MaterialDefinitionBase> materialCollection;
public NamedList<MaterialDefinitionBase> MaterialCollection
{
get => materialCollection;
set
{
OnPropertyChanged(value, materialCollection);
OnPropertyChanged(nameof(IsNotConcrete));
OnPropertyChanged(nameof(RowHeight));
}
}
public bool IsNotConcrete => MaterialCollection.Name != "Бетон";
private string materialClass;
private double youngModulus, compressiveStrengthCoef, tensileStrengthCoef, materialCoefInCompress, materialCoefInTension;
public string MaterialClass
{
get => materialClass;
set => OnPropertyChanged(value, ref materialClass);
}
public double YoungModulus
{
get => youngModulus;
set => OnPropertyChanged(value, ref youngModulus);
}
public double CompressiveStrengthCoef
{
get => compressiveStrengthCoef;
set => OnPropertyChanged(value, ref compressiveStrengthCoef);
}
public double TensileStrengthCoef
{
get => tensileStrengthCoef;
set => OnPropertyChanged(value, ref tensileStrengthCoef);
}
public double MaterialCoefInCompress
{
get => materialCoefInCompress;
set => OnPropertyChanged(value, ref materialCoefInCompress);
}
public double MaterialCoefInTension
{
get => materialCoefInTension;
set => OnPropertyChanged(value, ref materialCoefInTension);
}
public int RowHeight => IsNotConcrete ? 40 : 0;
public ICommand AddMaterial { get; }
public AddMaterialViewModel() { }
public AddMaterialViewModel(MaterialCatalogModel model, AddMaterialView view, MaterialCatalogViewModel materialCatalogViewModel)
{
this.model = model;
this.view = view;
this.materialCatalogViewModel = materialCatalogViewModel;
Materials = new ObservableCollection<NamedList<MaterialDefinitionBase>>(model.Materials);
MaterialCollection = Materials.First();
AddMaterial = new RelayCommand(o =>
{
if (MaterialCollection.Name == "Бетон")
this.materialCatalogViewModel.ConcreteDefinitions.Add(new ConcreteDefinition(MaterialClass, 0, CompressiveStrengthCoef, TensileStrengthCoef, MaterialCoefInCompress, MaterialCoefInTension));
if (MaterialCollection.Name == "Арматура")
this.materialCatalogViewModel.RebarDefinitions.Add(new RebarDefinition(MaterialClass, YoungModulus, CompressiveStrengthCoef, TensileStrengthCoef, MaterialCoefInCompress, MaterialCoefInTension));
});
}
}
}

View File

@@ -0,0 +1,41 @@
<Window x:Class="StructureHelper.ColorPickerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:ColorPickerViewModel}"
Title="Выбрать цвет" Height="200" Width="500" Topmost="True" ResizeMode="NoResize">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Красный"/>
<Slider Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="10" Value="{Binding Red}" Minimum="0" Maximum="255"/>
<TextBox Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="10" Text="{Binding Red}"/>
<Border Grid.Column="3" Grid.RowSpan="3" Margin="10" BorderBrush="Black" BorderThickness="1">
<Rectangle Fill="{Binding SelectedColor}"/>
</Border>
<TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Зеленый"/>
<Slider Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="10" Value="{Binding Green}" Minimum="0" Maximum="255"/>
<TextBox Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="10" Text="{Binding Green}"/>
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Синий"/>
<Slider Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="10" Value="{Binding Blue}" Minimum="0" Maximum="255"/>
<TextBox Grid.Row="2" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="10" Text="{Binding Blue}"/>
<Button Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Выбрать цвет" Command="{Binding SetColor}"/>
</Grid>
</Window>

View File

@@ -0,0 +1,17 @@
using System.Windows;
namespace StructureHelper
{
/// <summary>
/// Логика взаимодействия для ColorPickerView.xaml
/// </summary>
public partial class ColorPickerView : Window
{
public ColorPickerView(PrimitiveDefinition primitive)
{
var viewModel = new ColorPickerViewModel(primitive);
DataContext = viewModel;
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using System.Windows.Media;
using StructureHelper.Infrastructure;
namespace StructureHelper
{
public class ColorPickerViewModel : ViewModelBase
{
private int red, green, blue;
public int Red
{
get => red;
set => OnColorItemChanged(value, ref red);
}
public int Green
{
get => green;
set => OnColorItemChanged(value, ref green);
}
public int Blue
{
get => blue;
set => OnColorItemChanged(value, ref blue);
}
private SolidColorBrush selectedColor;
public SolidColorBrush SelectedColor
{
get => selectedColor;
set => OnPropertyChanged(value, selectedColor);
}
public ICommand SetColor { get; }
public ColorPickerViewModel(PrimitiveDefinitionBase primitive)
{
if (primitive != null)
{
var solidBrush = primitive.Brush;
Red = solidBrush.Color.R;
Green = solidBrush.Color.G;
Blue = solidBrush.Color.B;
SetColor = new RelayCommand(o => primitive.Brush = SelectedColor);
}
}
private void OnColorItemChanged(int value, ref int colorItem, [CallerMemberName] string propertyName = null)
{
if (value >= 0 && value <= 255 && Math.Abs(colorItem - value) > 0.001)
{
colorItem = value;
OnPropertyChanged(propertyName);
UpdateSelectedColor();
}
}
private void UpdateSelectedColor()
{
var color = Color.FromRgb((byte)Red, (byte)Green, (byte)Blue);
SelectedColor = new SolidColorBrush(color);
OnPropertyChanged(nameof(SelectedColor));
}
}
}

View File

@@ -0,0 +1,7 @@
namespace StructureHelper
{
public class MainModel
{
}
}

View File

@@ -0,0 +1,318 @@
<Window x:Class="StructureHelper.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:infrastructure="clr-namespace:StructureHelper.Infrastructure"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:MainViewModel}"
Title="StructureHelper" Height="700" Width="1000">
<Window.InputBindings>
<KeyBinding Command="{Binding SetParameters}" Key="Enter"/>
</Window.InputBindings>
<Window.Resources>
<DataTemplate x:Key="rectangleTemplate">
<DockPanel>
<Border x:Name="Border" Width="{Binding BorderWidth, Mode=TwoWay}" Height="{Binding BorderHeight, Mode=TwoWay}" Background="{Binding Brush, Mode=TwoWay}"
Opacity="{Binding Opacity, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveLeftButtonDown}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveLeftButtonUp}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseMove">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.BorderPreviewMouseMove}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<infrastructure:DoubleClickEventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveDoubleClick}" CommandParameter="{Binding}"/>
</infrastructure:DoubleClickEventTrigger>
</i:Interaction.Triggers>
<Border.ToolTip>
<ToolTip Background="White" BorderBrush="Black" BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Координата X:"/>
<TextBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding ShowedRectX}"/>
<TextBox Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Координата Y:"/>
<TextBox Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding ShowedRectY}"/>
<TextBox Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Ширина:"/>
<TextBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding BorderWidth}"/>
<TextBox Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Высота:"/>
<TextBox Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding BorderHeight}"/>
<TextBox Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Материал:"/>
<TextBox Grid.Row="4" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding MaterialName, Mode=TwoWay}"/>
</Grid>
</ToolTip>
</Border.ToolTip>
<Rectangle Name="testRect" Fill="{Binding Brush, Mode=TwoWay}" Width="20" Height="20" StrokeThickness="2" Stroke="{Binding Brush, Mode=TwoWay}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.LeftButtonDown}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.LeftButtonUp}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseMove">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PreviewMouseMove}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
</Border>
<Popup IsOpen="{Binding ParamsPanelVisibilty}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetPopupCanBeClosedTrue}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetPopupCanBeClosedFalse}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Border Background="White" BorderBrush="Black" BorderThickness="1">
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition Width="170"/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Координата X" Margin="10"/>
<TextBox Grid.Column="1" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RectParameterX, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Координата Y" Margin="10"/>
<TextBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RectParameterY, Mode=TwoWay}"/>
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Ширина" Margin="10"/>
<TextBox Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RectParameterWidth, Mode=TwoWay}"/>
<TextBlock Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Высота" Margin="10"/>
<TextBox Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RectParameterHeight, Mode=TwoWay}"/>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Материал" Margin="10"/>
<Button Grid.Row="4" Grid.Column="1" Margin="10" Background="White"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.OpenMaterialCatalogWithSelection}" CommandParameter="{Binding}"
Content="{Binding MaterialName, Mode=TwoWay}"/>
<TextBlock Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Цвет"/>
<Button Grid.Row="5" Grid.Column="1" Margin="10" Background="{Binding Brush, Mode=TwoWay}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetColor}" CommandParameter="{Binding}"/>
<TextBlock Grid.Row="6" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Прозрачность"/>
<TextBox Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" Margin="10,10,50,10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ParameterOpacity, Mode=TwoWay}"/>
<TextBlock Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Text="%" Margin="25,10"/>
<TextBlock Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Заблокировать объект" Grid.ColumnSpan="2"/>
<CheckBox Grid.Row="7" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ElementLock, Mode=TwoWay}"></CheckBox>
<TextBlock Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Z-порядок"/>
<StackPanel Grid.Row="8" Grid.Column="1" Orientation="Horizontal">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Width="50" Margin="10"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveIndex, Mode=TwoWay}"/>
<TextBlock VerticalAlignment="Center" Text="Max = "/>
<TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitivesCount, Mode=TwoWay}"/>
</StackPanel>
<Button Grid.Row="9" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Установить впереди всех" Margin="10"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetInFrontOfAll}" CommandParameter="{Binding}"/>
<Button Grid.Row="9" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Установить позади всех" Margin="10"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetInBackOfAll}" CommandParameter="{Binding}"/>
<Button Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" Content="Установить параметры"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetParameters}" CommandParameter="{Binding}"/>
</Grid>
</Border>
</Popup>
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="ellipseTemplate">
<DockPanel>
<Ellipse Width="{Binding Diameter}" Height="{Binding Diameter}" Fill="{Binding Brush, Mode=TwoWay}" Opacity="{Binding Opacity, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveLeftButtonDown}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveLeftButtonUp}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseMove">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.EllipsePreviewMouseMove}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<infrastructure:DoubleClickEventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveDoubleClick}" CommandParameter="{Binding}"/>
</infrastructure:DoubleClickEventTrigger>
</i:Interaction.Triggers>
<Ellipse.ToolTip>
<ToolTip Background="White" BorderBrush="Black" BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Координата центра X:"/>
<TextBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding ShowedEllipseX}"/>
<TextBox Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Координата центра Y:"/>
<TextBox Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding ShowedEllipseY}"/>
<TextBox Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Диаметр:"/>
<TextBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding ShowedDiameter}"/>
<TextBox Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="Материал:"/>
<TextBox Grid.Row="4" Grid.Column="1" VerticalAlignment="Center" Margin="3" BorderThickness="0" Text="{Binding MaterialName, Mode=TwoWay}"/>
</Grid>
</ToolTip>
</Ellipse.ToolTip>
</Ellipse>
<Popup IsOpen="{Binding ParamsPanelVisibilty}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetPopupCanBeClosedTrue}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetPopupCanBeClosedFalse}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Border Background="White" BorderBrush="Black" BorderThickness="1">
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition Width="170"/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Координата центра X" Margin="10"/>
<TextBox Grid.Column="1" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.EllipseParameterX, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Координата центра Y" Margin="10"/>
<TextBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.EllipseParameterY, Mode=TwoWay}"/>
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Площадь" Margin="10"/>
<TextBox Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.EllipseParameterSquare, Mode=TwoWay}"/>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Материал" Margin="10"/>
<Button Grid.Row="4" Grid.Column="1" Margin="10" Background="White"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.OpenMaterialCatalogWithSelection}" CommandParameter="{Binding}"
Content="{Binding MaterialName, Mode=TwoWay}"/>
<TextBlock Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Цвет"/>
<Button Grid.Row="5" Grid.Column="1" Margin="10" Background="{Binding Brush, Mode=TwoWay}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetColor}" CommandParameter="{Binding}"/>
<TextBlock Grid.Row="6" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Прозрачность"/>
<TextBox Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" Margin="10,10,50,10" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ParameterOpacity, Mode=TwoWay}"/>
<TextBlock Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Text="%" Margin="25,10"/>
<TextBlock Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Заблокировать объект" Grid.ColumnSpan="2"/>
<CheckBox Grid.Row="7" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ElementLock, Mode=TwoWay}"></CheckBox>
<TextBlock Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Text="Z-порядок"/>
<StackPanel Grid.Row="8" Grid.Column="1" Orientation="Horizontal">
<TextBox VerticalAlignment="Center" HorizontalAlignment="Left" Width="50" Margin="10"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitiveIndex, Mode=TwoWay}"/>
<TextBlock VerticalAlignment="Center" Text="Max = "/>
<TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PrimitivesCount, Mode=TwoWay}"/>
</StackPanel>
<Button Grid.Row="9" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Установить впереди всех" Margin="10"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetInFrontOfAll}" CommandParameter="{Binding}"/>
<Button Grid.Row="9" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Установить позади всех" Margin="10"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetInBackOfAll}" CommandParameter="{Binding}"/>
<Button Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" Content="Установить параметры"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SetParameters}" CommandParameter="{Binding}"/>
</Grid>
</Border>
</Popup>
</DockPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Border BorderBrush="Black" Background="White" BorderThickness="1" Margin="5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding ClearSelection}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<Canvas ClipToBounds="True" Width="{Binding CanvasWidth}" Height="{Binding CanvasHeight}">
<i:Interaction.Behaviors>
<local:MouseBehaviour MouseX="{Binding PanelX, Mode=OneWayToSource}" MouseY="{Binding PanelY, Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
<i:Interaction.Triggers>
<infrastructure:MouseWheelDownEventTrigger EventName="PreviewMouseWheel">
<i:InvokeCommandAction Command="{Binding ScaleCanvasDown}" CommandParameter="{Binding}"/>
</infrastructure:MouseWheelDownEventTrigger>
<infrastructure:MouseWheelUpEventTrigger EventName="PreviewMouseWheel">
<i:InvokeCommandAction Command="{Binding ScaleCanvasUp}" CommandParameter="{Binding}"/>
</infrastructure:MouseWheelUpEventTrigger>
</i:Interaction.Triggers>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ScaleValue}" ScaleY="{Binding ScaleValue}"
CenterX="{Binding ScrollPanelX}" CenterY="{Binding ScrollPanelY}"/>
</TransformGroup>
</Canvas.RenderTransform>
<Canvas.Background>
<DrawingBrush Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<GeometryGroup FillRule="EvenOdd">
<RectangleGeometry Rect="0,0,50,50"/>
<RectangleGeometry Rect="0,0,49.5,49.5"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
<Line X1="0" X2="{Binding XX2}" Y1="{Binding XY1}" Y2="{Binding XY1}" Stroke="Red" StrokeThickness="1"/>
<Line X1="{Binding YX1}" X2="{Binding YX1}" Y1="0" Y2="{Binding YY2}" Stroke="ForestGreen" StrokeThickness="1"/>
<ItemsControl ItemsSource="{Binding Primitives}" ItemTemplate="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}"/>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Canvas>
</ScrollViewer>
</Border>
<Button Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10" Content="Справочник" Command="{Binding OpenMaterialCatalog}"/>
<Button Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" Content="Добавить прямоугольник" Command="{Binding AddRectangle}"/>
<Button Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" Content="Добавить точку" Command="{Binding AddEllipse}"/>
</Grid>
</Window>

View File

@@ -0,0 +1,15 @@
using System.Windows;
namespace StructureHelper
{
public partial class MainView : Window
{
public MainView()
{
var model = new MainModel();
var viewModel = new MainViewModel(model, this);
DataContext = viewModel;
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,408 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using StructureHelper.Infrastructure;
namespace StructureHelper
{
public class MainViewModel : ViewModelBase
{
private MainModel rectanglesModel;
private MainView rectanglesView;
public ObservableCollection<RectangleDefinition> Rectangles { get; set; }
public ObservableCollection<EllipseDefinition> Ellipses { get; set; }
public ObservableCollection<PrimitiveDefinition> Primitives { get; set; }
public ICommand AddRectangle { get; }
private double panelX, panelY, scrollPanelX, scrollPanelY;
public double PanelX
{
get => panelX;
set => OnPropertyChanged(value, ref panelX);
}
public double PanelY
{
get => panelY;
set => OnPropertyChanged(value, ref panelY);
}
public double ScrollPanelX
{
get => scrollPanelX;
set => OnPropertyChanged(value, ref scrollPanelX);
}
public double ScrollPanelY
{
get => scrollPanelY;
set => OnPropertyChanged(value, ref scrollPanelY);
}
private double rectParameterX, rectParameterY, rectParameterWidth, rectParameterHeight;
public double RectParameterX
{
get => rectParameterX;
set => OnPropertyChanged(value, ref rectParameterX);
}
public double RectParameterY
{
get => rectParameterY;
set => OnPropertyChanged(value, ref rectParameterY);
}
public double RectParameterWidth
{
get => rectParameterWidth;
set => OnPropertyChanged(value, ref rectParameterWidth);
}
public double RectParameterHeight
{
get => rectParameterHeight;
set => OnPropertyChanged(value, ref rectParameterHeight);
}
private double parameterOpacity = 0;
public double ParameterOpacity
{
get => parameterOpacity;
set
{
if (value >= 0 && value <= 100)
OnPropertyChanged(value, ref parameterOpacity);
}
}
private double ellipseParameterX, ellipseParameterY, ellipseParameterSquare;
public double EllipseParameterX
{
get => ellipseParameterX;
set => OnPropertyChanged(value, ref ellipseParameterX);
}
public double EllipseParameterY
{
get => ellipseParameterY;
set => OnPropertyChanged(value, ref ellipseParameterY);
}
public double EllipseParameterSquare
{
get => ellipseParameterSquare;
set => OnPropertyChanged(value, ref ellipseParameterSquare);
}
private bool elementLock;
public bool ElementLock
{
get => elementLock;
set => OnPropertyChanged(value, ref elementLock);
}
private int primitivesCount;
public int PrimitivesCount
{
get => primitivesCount;
set => OnPropertyChanged(value, ref primitivesCount);
}
private int primitiveIndex = 1;
public int PrimitiveIndex
{
get => primitiveIndex;
set
{
if (value >= 0 && value <= primitivesCount)
OnPropertyChanged(value, ref primitiveIndex);
}
}
private double scaleValue = 1.0;
public double ScaleValue
{
get => scaleValue;
set => OnPropertyChanged(value, ref scaleValue);
}
private double canvasWidth, canvasHeight, xX2, xY1, yX1, yY2;
public double CanvasWidth
{
get => canvasWidth;
set => OnPropertyChanged(value, ref canvasWidth);
}
public double CanvasHeight
{
get => canvasHeight;
set => OnPropertyChanged(value, ref canvasHeight);
}
public double XX2
{
get => xX2;
set => OnPropertyChanged(value, ref xX2);
}
public double XY1
{
get => xY1;
set => OnPropertyChanged(value, ref xY1);
}
public double YX1
{
get => yX1;
set => OnPropertyChanged(value, ref yX1);
}
public double YY2
{
get => yY2;
set => OnPropertyChanged(value, ref yY2);
}
private double delta = 0.5;
public ICommand LeftButtonDown { get; }
public ICommand LeftButtonUp { get; }
public ICommand PreviewMouseMove { get; }
public ICommand PrimitiveLeftButtonDown { get; }
public ICommand PrimitiveLeftButtonUp { get; }
public ICommand BorderPreviewMouseMove { get; }
public ICommand PrimitiveDoubleClick { get; }
public ICommand SetParameters { get; }
public ICommand ClearSelection { get; }
public ICommand SetPopupCanBeClosedTrue { get; }
public ICommand SetPopupCanBeClosedFalse { get; }
public ICommand OpenMaterialCatalog { get; }
public ICommand OpenMaterialCatalogWithSelection { get; }
public ICommand SetColor { get; }
public ICommand SetInFrontOfAll { get; }
public ICommand SetInBackOfAll { get; }
public ICommand ScaleCanvasDown { get; }
public ICommand ScaleCanvasUp { get; }
public ICommand AddEllipse { get; }
public ICommand EllipsePreviewMouseMove { get; }
public MainViewModel() { }
public MainViewModel(MainModel rectanglesModel, MainView rectanglesView)
{
this.rectanglesModel = rectanglesModel;
this.rectanglesView = rectanglesView;
CanvasWidth = 1500;
CanvasHeight = 1000;
XX2 = CanvasWidth;
XY1 = CanvasHeight / 2;
YX1 = CanvasWidth / 2;
YY2 = CanvasHeight;
BorderPreviewMouseMove = new RelayCommand(o =>
{
var rect = o as RectangleDefinition;
if (rect.Captured && !rect.BorderCaptured && !rect.ElementLock)
{
var deltaX = rect.BorderWidth / 2;
var deltaY = rect.BorderHeight / 2;
if (rect.ShowedRectX % 10 <= delta || rect.ShowedRectX % 10 >= 10 - delta)
rect.ShowedRectX = Math.Round((PanelX - deltaX - YX1) / 10) * 10;
else
rect.ShowedRectX = PanelX - deltaX - YX1;
if (rect.ShowedRectY % 10 <= delta || rect.ShowedRectY % 10 >= 10 - delta)
rect.ShowedRectY = -(Math.Round((PanelY - deltaY - XY1 + rect.BorderHeight) / 10) * 10);
else
rect.ShowedRectY = -(PanelY - deltaY - XY1 + rect.BorderHeight);
}
if (rect.ParameterCaptured)
{
RectParameterX = rect.ShowedRectX;
RectParameterY = rect.ShowedRectY;
RectParameterWidth = rect.BorderWidth;
RectParameterHeight = rect.BorderHeight;
ParameterOpacity = rect.ShowedOpacity;
ElementLock = rect.ElementLock;
}
});
PrimitiveLeftButtonUp = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
primitive.Captured = false;
});
PrimitiveLeftButtonDown = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
primitive.Captured = true;
foreach (var primitiveDefinition in Primitives)
primitiveDefinition.ParameterCaptured = false;
primitive.ParameterCaptured = true;
});
LeftButtonUp = new RelayCommand(o =>
{
var rect = o as RectangleDefinition;
rect.BorderCaptured = false;
});
LeftButtonDown = new RelayCommand(o =>
{
var rect = o as RectangleDefinition;
rect.BorderCaptured = true;
});
PreviewMouseMove = new RelayCommand(o =>
{
var rect = o as RectangleDefinition;
if (rect.BorderCaptured && rect.Captured && !rect.ElementLock)
{
if (rect.BorderWidth % 10 < delta || rect.BorderWidth % 10 >= delta)
rect.BorderWidth = Math.Round(PanelX / 10) * 10 - rect.RectX + 10;
else
rect.BorderWidth = PanelX - rect.RectX + 10;
if (rect.BorderHeight % 10 < delta || rect.BorderHeight % 10 >= delta)
rect.BorderHeight = Math.Round(PanelY / 10) * 10 - rect.RectY + 10;
else
rect.BorderHeight = PanelY - rect.RectY + 10;
}
});
SetParameters = new RelayCommand(o =>
{
var primitive = Primitives.FirstOrDefault(x => x.ParameterCaptured);
primitive.ElementLock = ElementLock;
primitive.ShowedOpacity = ParameterOpacity;
Primitives.MoveElementToSelectedIndex(primitive, PrimitiveIndex);
foreach (var primitiveDefinition in Primitives)
primitiveDefinition.ShowedZIndex = Primitives.IndexOf(primitiveDefinition) + 1;
if (primitive is RectangleDefinition rectangle)
{
rectangle.ShowedRectX = RectParameterX;
rectangle.ShowedRectY = RectParameterY;
rectangle.BorderWidth = RectParameterWidth;
rectangle.BorderHeight = RectParameterHeight;
}
if (primitive is EllipseDefinition ellipse)
{
ellipse.Square = EllipseParameterSquare;
ellipse.ShowedEllipseX = EllipseParameterX;
ellipse.ShowedEllipseY = EllipseParameterY;
}
});
ClearSelection = new RelayCommand(o =>
{
var primitive = Primitives.FirstOrDefault(x => x.ParamsPanelVisibilty);
if (primitive != null && primitive.PopupCanBeClosed)
primitive.ParamsPanelVisibilty = false;
});
PrimitiveDoubleClick = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
primitive.PopupCanBeClosed = false;
primitive.Captured = false;
primitive.ParamsPanelVisibilty = true;
if (primitive is RectangleDefinition rect)
rect.BorderCaptured = false;
});
SetPopupCanBeClosedTrue = new RelayCommand(o =>
{
var primitiveParamsVisible = Primitives.FirstOrDefault(x => x.ParameterCaptured);
primitiveParamsVisible.PopupCanBeClosed = true;
});
SetPopupCanBeClosedFalse = new RelayCommand(o =>
{
var primitiveParamsVisible = Primitives.FirstOrDefault(x => x.ParameterCaptured);
primitiveParamsVisible.PopupCanBeClosed = false;
});
OpenMaterialCatalog = new RelayCommand(o =>
{
var materialCatalogView = new MaterialCatalogView();
materialCatalogView.ShowDialog();
});
OpenMaterialCatalogWithSelection = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
var materialCatalogView = new MaterialCatalogView(true, primitive);
materialCatalogView.ShowDialog();
});
SetColor = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
var colorPickerView = new ColorPickerView(primitive);
colorPickerView.ShowDialog();
});
SetInFrontOfAll = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
foreach (var primitiveDefinition in Primitives)
if (primitiveDefinition.ShowedZIndex > primitive.ShowedZIndex && primitiveDefinition != primitive)
primitiveDefinition.ShowedZIndex--;
primitive.ShowedZIndex = PrimitivesCount;
OnPropertyChanged(nameof(primitive.ShowedZIndex));
});
SetInBackOfAll = new RelayCommand(o =>
{
var primitive = o as PrimitiveDefinition;
foreach (var primitiveDefinition in Primitives)
if (primitiveDefinition.ShowedZIndex < primitive.ShowedZIndex && primitiveDefinition != primitive)
primitiveDefinition.ShowedZIndex++;
primitive.ShowedZIndex = 1;
OnPropertyChanged(nameof(primitive.ShowedZIndex));
});
ScaleCanvasDown = new RelayCommand(o =>
{
var scaleRate = 1.1;
ScrollPanelX = PanelX;
ScrollPanelY = PanelY;
ScaleValue *= scaleRate;
});
ScaleCanvasUp = new RelayCommand(o =>
{
var scaleRate = 1.1;
ScrollPanelX = PanelX;
ScrollPanelY = PanelY;
ScaleValue /= scaleRate;
});
Primitives = new ObservableCollection<PrimitiveDefinition>();
Rectangles = new ObservableCollection<RectangleDefinition>();
Ellipses = new ObservableCollection<EllipseDefinition>();
AddRectangle = new RelayCommand(o =>
{
var rectangle = new RectangleDefinition(60, 40, YX1, XY1);
Rectangles.Add(rectangle);
Primitives.Add(rectangle);
PrimitivesCount = Primitives.Count;
});
AddEllipse = new RelayCommand(o =>
{
var ellipse = new EllipseDefinition(2000, YX1, XY1);
Ellipses.Add(ellipse);
Primitives.Add(ellipse);
PrimitivesCount = Primitives.Count;
});
EllipsePreviewMouseMove = new RelayCommand(o =>
{
if (!(o is EllipseDefinition ellipse)) return;
if (ellipse.Captured && !ellipse.ElementLock)
{
var delta = ellipse.Diameter / 2;
if (ellipse.ShowedEllipseX % 10 <= delta || ellipse.ShowedEllipseX % 10 >= 10 - delta)
ellipse.ShowedEllipseX = Math.Round((PanelX - YX1) / 10) * 10;
else
ellipse.ShowedEllipseX = PanelX - delta - YX1;
if (ellipse.ShowedEllipseY % 10 <= delta || ellipse.ShowedEllipseY % 10 >= 10 - delta)
ellipse.ShowedEllipseY = -(Math.Round((PanelY - XY1) / 10) * 10);
else
ellipse.ShowedEllipseY = -(PanelY - delta - XY1);
}
if (ellipse.ParameterCaptured)
{
EllipseParameterX = ellipse.ShowedEllipseX;
EllipseParameterY = ellipse.ShowedEllipseY;
EllipseParameterSquare = ellipse.Square;
ParameterOpacity = ellipse.ShowedOpacity;
ElementLock = ellipse.ElementLock;
}
});
}
}
}

5
packages.config Normal file
View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net472" />
<package id="System.Windows.Interactivity.WPF" version="2.0.20525" targetFramework="net472" />
</packages>