Unit constants was added

This commit is contained in:
Evgeny Redikultsev
2022-11-13 20:12:28 +05:00
parent 1e98e2cc57
commit e68ae14963
18 changed files with 152 additions and 40 deletions

View File

@@ -7,6 +7,7 @@
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Infrastructure/UI/Styles.xaml"/> <ResourceDictionary Source="Infrastructure/UI/Styles.xaml"/>
<ResourceDictionary Source="Infrastructure/UI/Resources/ShapeEditTemplates.xaml"/> <ResourceDictionary Source="Infrastructure/UI/Resources/ShapeEditTemplates.xaml"/>
<ResourceDictionary Source="Infrastructure/UI/Resources/Converters.xaml"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>

View File

@@ -160,6 +160,7 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
private double crossLineY; private double crossLineY;
private double sumAboveLine; private double sumAboveLine;
private double sumUnderLine; private double sumUnderLine;
private Line previosLine;
const int RangeNumber = 16; const int RangeNumber = 16;
public FieldViewerViewModel() public FieldViewerViewModel()
@@ -311,16 +312,16 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
if (crossLineX == 0d) if (crossLineX == 0d)
{ {
line.X1 = - width / 2d - dX; line.X1 = - width / 2d - dX;
line.Y1 = - crossLineY - dY; line.Y1 = - crossLineY + dY;
line.X2 = width / 2d - dX; line.X2 = width / 2d - dX;
line.Y2 = - crossLineY - dY; line.Y2 = - crossLineY + dY;
} }
else if (crossLineY == 0d) else if (crossLineY == 0d)
{ {
line.X1 = crossLineX - dX; line.X1 = crossLineX - dX;
line.Y1 = heigth / 2 - dY; line.Y1 = heigth / 2 + dY;
line.X2 = crossLineX - dX; line.X2 = crossLineX - dX;
line.Y2 = -heigth / 2 - dY; line.Y2 = -heigth / 2 + dY;
} }
else else
{ {
@@ -334,6 +335,12 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
line.Fill = brush; line.Fill = brush;
line.Stroke = brush; line.Stroke = brush;
line.StrokeThickness = (width + heigth) / 100; line.StrokeThickness = (width + heigth) / 100;
if (previosLine != null)
{
try { WorkPlaneCanvas.Children.Remove(previosLine);}
catch (Exception) {}
}
previosLine = line;
WorkPlaneCanvas.Children.Add(line); WorkPlaneCanvas.Children.Add(line);
} }
private double GetPointOfCrossLine(double x) private double GetPointOfCrossLine(double x)

View File

@@ -17,7 +17,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
double val; double val;
if (value != null) { val = (double)value; } if (value != null) { val = (double)value; }
else { throw new Exception($"{unitName} value is null"); } else { throw new Exception($"{unitName} value is null"); }
val *= UnitConstatnts.LengthConstant * UnitConstatnts.LengthConstant; val *= UnitConstatnts.Length * UnitConstatnts.Length;
return val; return val;
} }
@@ -30,7 +30,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
double.TryParse(strVal, out val); double.TryParse(strVal, out val);
} }
else { throw new Exception($"{unitName} value is null"); } else { throw new Exception($"{unitName} value is null"); }
val /= (UnitConstatnts.LengthConstant * UnitConstatnts.LengthConstant); val /= (UnitConstatnts.Length * UnitConstatnts.Length);
return val; return val;
} }
} }

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace StructureHelper.Infrastructure.UI.Converters.Units
{
internal class Force : UnitBase
{
private double coeffficient = UnitConstatnts.Force;
public override string unitName { get => "Force"; }
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double val;
if (value != null) { val = (double)value; }
else { throw new Exception($"{unitName} value is null"); }
val *= coeffficient;
return val;
}
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
double val;
if (value != null)
{
var strVal = value as string;
double.TryParse(strVal, out val);
}
else { throw new Exception($"{unitName} value is null"); }
val /= coeffficient;
return val;
}
}
}

View File

@@ -17,7 +17,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
double val; double val;
if (value != null) { val = (double)value; } if (value != null) { val = (double)value; }
else { throw new Exception($"{unitName} value is null"); } else { throw new Exception($"{unitName} value is null"); }
val *= UnitConstatnts.LengthConstant; val *= UnitConstatnts.Length;
return val; return val;
} }
@@ -30,7 +30,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
double.TryParse(strVal, out val); double.TryParse(strVal, out val);
} }
else { throw new Exception($"{unitName} value is null"); } else { throw new Exception($"{unitName} value is null"); }
val /= UnitConstatnts.LengthConstant; val /= UnitConstatnts.Length;
return val; return val;
} }
} }

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace StructureHelper.Infrastructure.UI.Converters.Units
{
internal class Stress : UnitBase
{
private double coeffficient = UnitConstatnts.Stress;
public override string unitName { get => "Stress"; }
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double val;
if (value != null) { val = (double)value; }
else { throw new Exception($"{unitName} value is null"); }
val *= coeffficient;
return val;
}
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
double val;
if (value != null)
{
var strVal = value as string;
double.TryParse(strVal, out val);
}
else { throw new Exception($"{unitName} value is null"); }
val /= coeffficient;
return val;
}
}
}

View File

@@ -8,6 +8,8 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
{ {
internal static class UnitConstatnts internal static class UnitConstatnts
{ {
public static double LengthConstant = 1000d; public static double Length = 1e3d;
public static double Force = 1e-3d;
public static double Stress = 1e-6d;
} }
} }

View File

@@ -337,12 +337,12 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
{ {
if (this is Rectangle) if (this is Rectangle)
{ {
X = showedX + OwnerVm.YX1 / UnitConstatnts.LengthConstant; X = showedX + OwnerVm.YX1 / UnitConstatnts.Length;
} }
else if (this is Point) else if (this is Point)
{ {
Point point = this as Point; Point point = this as Point;
X = showedX + OwnerVm.YX1 / UnitConstatnts.LengthConstant; X = showedX + OwnerVm.YX1 / UnitConstatnts.Length;
} }
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); } else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); }
} }
@@ -350,12 +350,12 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
{ {
if (this is Rectangle) if (this is Rectangle)
{ {
Y = -showedY + OwnerVm.XY1 / UnitConstatnts.LengthConstant - PrimitiveHeight; Y = -showedY + OwnerVm.XY1 / UnitConstatnts.Length - PrimitiveHeight;
} }
else if (this is Point) else if (this is Point)
{ {
Point point = this as Point; Point point = this as Point;
Y = -showedY + OwnerVm.XY1 / UnitConstatnts.LengthConstant - point.Diameter; Y = -showedY + OwnerVm.XY1 / UnitConstatnts.Length - point.Diameter;
} }
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); } else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); }
} }

View File

@@ -0,0 +1,12 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:convertersCommon ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Common"
xmlns:convertersUnits ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Units">
<convertersCommon:InvertBoolConverter x:Key="InvertBoolConverter"/>
<convertersUnits:Length x:Key="LengthConverter"/>
<convertersUnits:Area x:Key="AreaConverter"/>
<convertersUnits:Force x:Key="ForceConverter"/>
<convertersUnits:Stress x:Key="StressConverter"/>
</ResourceDictionary>

View File

@@ -12,5 +12,6 @@ namespace StructureHelper.Services.ResultViewers
{ {
string Name { get; } string Name { get; }
Func<IStrainMatrix, INdm, double> ResultFunction { get; } Func<IStrainMatrix, INdm, double> ResultFunction { get; }
double UnitFactor { get; }
} }
} }

View File

@@ -12,5 +12,11 @@ namespace StructureHelper.Services.ResultViewers
{ {
public string Name { get; set; } public string Name { get; set; }
public Func<IStrainMatrix, INdm, double> ResultFunction { get; set; } public Func<IStrainMatrix, INdm, double> ResultFunction { get; set; }
public double UnitFactor { get; set; }
public ResultFunc()
{
UnitFactor = 1d;
}
} }
} }

View File

@@ -1,4 +1,5 @@
using LoaderCalculator.Logics; using LoaderCalculator.Logics;
using StructureHelper.Infrastructure.UI.Converters.Units;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -17,12 +18,12 @@ namespace StructureHelper.Services.ResultViewers
resultFuncs.Add(new ResultFunc() { Name = "Total Strain with prestrain", ResultFunction = stressLogic.GetTotalStrainWithPresrain }); resultFuncs.Add(new ResultFunc() { Name = "Total Strain with prestrain", ResultFunction = stressLogic.GetTotalStrainWithPresrain });
resultFuncs.Add(new ResultFunc() { Name = "Elastic Strain", ResultFunction = stressLogic.GetElasticStrain }); resultFuncs.Add(new ResultFunc() { Name = "Elastic Strain", ResultFunction = stressLogic.GetElasticStrain });
resultFuncs.Add(new ResultFunc() { Name = "Plastic Strain", ResultFunction = stressLogic.GetPlasticStrain }); resultFuncs.Add(new ResultFunc() { Name = "Plastic Strain", ResultFunction = stressLogic.GetPlasticStrain });
resultFuncs.Add(new ResultFunc() { Name = "Stress", ResultFunction = stressLogic.GetStress }); resultFuncs.Add(new ResultFunc() { Name = "Stress", ResultFunction = stressLogic.GetStress, UnitFactor = UnitConstatnts.Stress });
resultFuncs.Add(new ResultFunc() { Name = "Secant modulus", ResultFunction = stressLogic.GetSecantModulus }); resultFuncs.Add(new ResultFunc() { Name = "Secant modulus", ResultFunction = stressLogic.GetSecantModulus, UnitFactor = UnitConstatnts.Stress });
resultFuncs.Add(new ResultFunc() { Name = "Modulus degradation", ResultFunction = stressLogic.GetModulusDegradation }); resultFuncs.Add(new ResultFunc() { Name = "Modulus degradation", ResultFunction = stressLogic.GetModulusDegradation });
resultFuncs.Add(new ResultFunc() { Name = "Force", ResultFunction = stressLogic.GetForce }); resultFuncs.Add(new ResultFunc() { Name = "Force", ResultFunction = stressLogic.GetForce, UnitFactor = UnitConstatnts.Force });
resultFuncs.Add(new ResultFunc() { Name = "Moment X", ResultFunction = stressLogic.GetMomentX }); resultFuncs.Add(new ResultFunc() { Name = "Moment X", ResultFunction = stressLogic.GetMomentX, UnitFactor = UnitConstatnts.Force });
resultFuncs.Add(new ResultFunc() { Name = "Moment Y", ResultFunction = stressLogic.GetMomentY }); resultFuncs.Add(new ResultFunc() { Name = "Moment Y", ResultFunction = stressLogic.GetMomentY, UnitFactor = UnitConstatnts.Force });
return resultFuncs; return resultFuncs;
} }
} }

View File

@@ -29,7 +29,7 @@ namespace StructureHelper.Services.ResultViewers
List<IValuePrimitive> primitives = new List<IValuePrimitive>(); List<IValuePrimitive> primitives = new List<IValuePrimitive>();
foreach (INdm ndm in ndms) foreach (INdm ndm in ndms)
{ {
double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm); double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm) * valDelegate.UnitFactor;
IValuePrimitive valuePrimitive; IValuePrimitive valuePrimitive;
if (ndm is IRectangleNdm) if (ndm is IRectangleNdm)
{ {

View File

@@ -135,6 +135,8 @@
<Compile Include="Infrastructure\Enums\PrimitiveType.cs" /> <Compile Include="Infrastructure\Enums\PrimitiveType.cs" />
<Compile Include="Infrastructure\UI\Converters\Common\InvertBoolConverter.cs" /> <Compile Include="Infrastructure\UI\Converters\Common\InvertBoolConverter.cs" />
<Compile Include="Infrastructure\UI\Converters\Units\Area.cs" /> <Compile Include="Infrastructure\UI\Converters\Units\Area.cs" />
<Compile Include="Infrastructure\UI\Converters\Units\Stress.cs" />
<Compile Include="Infrastructure\UI\Converters\Units\Force.cs" />
<Compile Include="Infrastructure\UI\Converters\Units\Length.cs" /> <Compile Include="Infrastructure\UI\Converters\Units\Length.cs" />
<Compile Include="Infrastructure\UI\Converters\Units\UnitBase.cs" /> <Compile Include="Infrastructure\UI\Converters\Units\UnitBase.cs" />
<Compile Include="Infrastructure\UI\Converters\Units\UnitConstatnts.cs" /> <Compile Include="Infrastructure\UI\Converters\Units\UnitConstatnts.cs" />
@@ -229,6 +231,10 @@
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Include="Infrastructure\UI\Resources\Converters.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Infrastructure\UI\Resources\ShapeEditTemplates.xaml"> <Page Include="Infrastructure\UI\Resources\ShapeEditTemplates.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -35,9 +35,9 @@
SelectedItem="{Binding Path=SelectedCombination}"> SelectedItem="{Binding Path=SelectedCombination}">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridCheckBoxColumn Header="Active" Binding="{Binding Path=TakeInCalculate}"/> <DataGridCheckBoxColumn Header="Active" Binding="{Binding Path=TakeInCalculate}"/>
<DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=ForceMatrix.Mx}"/> <DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=ForceMatrix.Mx, Converter={StaticResource ForceConverter}}"/>
<DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=ForceMatrix.My}"/> <DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=ForceMatrix.My, Converter={StaticResource ForceConverter}}"/>
<DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=ForceMatrix.Nz}"/> <DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=ForceMatrix.Nz, Converter={StaticResource ForceConverter}}"/>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">

View File

@@ -25,12 +25,15 @@
</DataGrid.RowStyle> </DataGrid.RowStyle>
<DataGrid.Columns> <DataGrid.Columns>
<DataGridCheckBoxColumn Header="Valid" Binding="{Binding Path=IsValid}"/> <DataGridCheckBoxColumn Header="Valid" Binding="{Binding Path=IsValid}"/>
<DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Mx}"/> <DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Mx, Converter={StaticResource ForceConverter}}"/>
<DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.My}"/> <DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.My, Converter={StaticResource ForceConverter}}"/>
<DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Nz}"/> <DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Nz, Converter={StaticResource ForceConverter}}"/>
<DataGridTextColumn Header="Accuracy" Width="90" Binding="{Binding Path=LoaderResults.AccuracyRate}"/> <DataGridTextColumn Header="Accuracy" Width="90" Binding="{Binding Path=LoaderResults.AccuracyRate}"/>
<DataGridTextColumn Header="Max Iteration" Width="90" Binding="{Binding Path=LoaderResults.IterationCounter}"/> <DataGridTextColumn Header="Max Iteration" Width="90" Binding="{Binding Path=LoaderResults.IterationCounter}"/>
<DataGridTextColumn Header="Description" Width="300" Binding="{Binding Path=Desctription}"/> <DataGridTextColumn Header="Description" Width="300" Binding="{Binding Path=Desctription}"/>
<DataGridTextColumn Header="Kx" Width="90" Binding="{Binding LoaderResults.ForceStrainPair.StrainMatrix.Kx}"/>
<DataGridTextColumn Header="Ky" Width="90" Binding="{Binding LoaderResults.ForceStrainPair.StrainMatrix.Ky}"/>
<DataGridTextColumn Header="EpsZ" Width="90" Binding="{Binding LoaderResults.ForceStrainPair.StrainMatrix.EpsZ}"/>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">

View File

@@ -287,7 +287,7 @@ namespace StructureHelper.Windows.MainWindow
Primitives.Add(primitive); Primitives.Add(primitive);
PrimitiveRepository.Add(primitive); PrimitiveRepository.Add(primitive);
} }
AddCaseLoads(50e3d, 50e3d, 0d); AddCaseLoads(-50e3d, 50e3d, 0d);
}); });
AddColumnCase = new RelayCommand(o => AddColumnCase = new RelayCommand(o =>
@@ -454,11 +454,11 @@ namespace StructureHelper.Windows.MainWindow
double[] xs = new double[] { -width / 2 + gap, width / 2 - gap }; double[] xs = new double[] { -width / 2 + gap, width / 2 - gap };
double[] ys = new double[] { -height / 2 + gap, height / 2 - gap }; double[] ys = new double[] { -height / 2 + gap, height / 2 - gap };
yield return new Rectangle(width, height, 0, 0, this) { HeadMaterial = concrete }; yield return new Rectangle(width, height, 0, 0, this) { HeadMaterial = concrete, Name = "Concrete block" };
yield return new Point(area1, xs[0], ys[0], this) { HeadMaterial = reinforcement }; yield return new Point(area1, xs[0], ys[0], this) { HeadMaterial = reinforcement, Name = "Left bottom point" };
yield return new Point(area1, xs[1], ys[0], this) { HeadMaterial = reinforcement }; yield return new Point(area1, xs[1], ys[0], this) { HeadMaterial = reinforcement, Name = "Right bottom point" };
yield return new Point(area2, xs[0], ys[1], this) { HeadMaterial = reinforcement }; yield return new Point(area2, xs[0], ys[1], this) { HeadMaterial = reinforcement, Name = "Left top point" };
yield return new Point(area2, xs[1], ys[1], this) { HeadMaterial = reinforcement }; yield return new Point(area2, xs[1], ys[1], this) { HeadMaterial = reinforcement, Name = "Right top point" };
if (template.WidthCount > 2) if (template.WidthCount > 2)
{ {
@@ -466,8 +466,8 @@ namespace StructureHelper.Windows.MainWindow
double dist = (xs[1] - xs[0]) / count; double dist = (xs[1] - xs[0]) / count;
for (int i = 1; i < count; i++) for (int i = 1; i < count; i++)
{ {
yield return new Point(area1, xs[0] + dist * i, ys[0], this) { HeadMaterial = reinforcement }; yield return new Point(area1, xs[0] + dist * i, ys[0], this) { HeadMaterial = reinforcement, Name = $"Bottom point {i}" };
yield return new Point(area2, xs[0] + dist * i, ys[1], this) { HeadMaterial = reinforcement }; yield return new Point(area2, xs[0] + dist * i, ys[1], this) { HeadMaterial = reinforcement, Name = $"Top point {i}" };
} }
} }
@@ -477,8 +477,8 @@ namespace StructureHelper.Windows.MainWindow
double dist = (ys[1] - ys[0]) / count; double dist = (ys[1] - ys[0]) / count;
for (int i = 1; i < count; i++) for (int i = 1; i < count; i++)
{ {
yield return new Point(area1, xs[0], ys[0] + dist * i, this) { HeadMaterial = reinforcement }; yield return new Point(area1, xs[0], ys[0] + dist * i, this) { HeadMaterial = reinforcement, Name = $"Left point {i}" };
yield return new Point(area1, xs[1], ys[0] + dist * i, this) { HeadMaterial = reinforcement }; yield return new Point(area1, xs[1], ys[0] + dist * i, this) { HeadMaterial = reinforcement, Name = $"Right point {i}" };
} }
} }
} }

View File

@@ -5,15 +5,10 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper.Windows.PrimitiveProperiesWindow" xmlns:local="clr-namespace:StructureHelper.Windows.PrimitiveProperiesWindow"
xmlns:vm="clr-namespace:StructureHelper.Windows.ViewModels.PrimitiveProperties" xmlns:vm="clr-namespace:StructureHelper.Windows.ViewModels.PrimitiveProperties"
xmlns:convertersCommon ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Common"
xmlns:convertersUnits ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Units"
d:DataContext="{d:DesignInstance vm:PrimitivePropertiesViewModel}" d:DataContext="{d:DesignInstance vm:PrimitivePropertiesViewModel}"
mc:Ignorable="d" mc:Ignorable="d"
Title="PrimitiveProperties" Height="450" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"> Title="PrimitiveProperties" Height="450" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Window.Resources> <Window.Resources>
<convertersCommon:InvertBoolConverter x:Key="InvertBoolConverter"/>
<convertersUnits:Length x:Key="LengthConverter"/>
<convertersUnits:Area x:Key="AreaConverter"/>
<DataTemplate x:Key="RectangleProperties"> <DataTemplate x:Key="RectangleProperties">
<Expander Header="Rectangle" IsExpanded="True"> <Expander Header="Rectangle" IsExpanded="True">
<Grid> <Grid>