TransporteUnion Terminado
This commit is contained in:
parent
268b66ad76
commit
c1ac20964e
1
App.xaml
1
App.xaml
|
@ -14,6 +14,7 @@
|
||||||
<local:DoubleToFormattedStringConverter x:Key="doubleFormatter"/>
|
<local:DoubleToFormattedStringConverter x:Key="doubleFormatter"/>
|
||||||
<local:BrushToColorNameConverter x:Key="BrushToColorNameConverter"/>
|
<local:BrushToColorNameConverter x:Key="BrushToColorNameConverter"/>
|
||||||
<local:VerticalPositionConverter x:Key="VerticalPositionConverter"/>
|
<local:VerticalPositionConverter x:Key="VerticalPositionConverter"/>
|
||||||
|
<local:SumConverter x:Key="SumConverter" />
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace CtrEditor
|
||||||
|
|
||||||
private readonly DispatcherTimer _timerSimulacion;
|
private readonly DispatcherTimer _timerSimulacion;
|
||||||
|
|
||||||
|
public Canvas MainCanvas;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private DatosDeTrabajo datosDeTrabajo;
|
private DatosDeTrabajo datosDeTrabajo;
|
||||||
|
|
||||||
|
@ -356,7 +358,7 @@ namespace CtrEditor
|
||||||
stopwatch_SimModel_last = stopwatch_Sim.Elapsed.TotalMilliseconds;
|
stopwatch_SimModel_last = stopwatch_Sim.Elapsed.TotalMilliseconds;
|
||||||
|
|
||||||
// Eliminar el diseño de Debug luego de 2 segundos
|
// Eliminar el diseño de Debug luego de 2 segundos
|
||||||
if (TiempoDesdeStartSimulacion > 2000)
|
if (TiempoDesdeStartSimulacion > 12000)
|
||||||
simulationManager.Debug_ClearSimulationShapes();
|
simulationManager.Debug_ClearSimulationShapes();
|
||||||
else
|
else
|
||||||
TiempoDesdeStartSimulacion += (float)elapsedMilliseconds;
|
TiempoDesdeStartSimulacion += (float)elapsedMilliseconds;
|
||||||
|
|
|
@ -65,6 +65,7 @@ namespace CtrEditor
|
||||||
viewModel.ImageSelected += ViewModel_ImageSelected;
|
viewModel.ImageSelected += ViewModel_ImageSelected;
|
||||||
viewModel?.LoadInitialData(); // Carga la primera imagen por defecto una vez cargada la ventana principal
|
viewModel?.LoadInitialData(); // Carga la primera imagen por defecto una vez cargada la ventana principal
|
||||||
viewModel.simulationManager.DebugCanvas = ImagenEnTrabajoCanvas;
|
viewModel.simulationManager.DebugCanvas = ImagenEnTrabajoCanvas;
|
||||||
|
viewModel.MainCanvas = ImagenEnTrabajoCanvas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<!-- Define the VisualBrush for the conveyor belt pattern -->
|
<!-- Define the VisualBrush for the conveyor belt pattern -->
|
||||||
<VisualBrush x:Key="BeltBrush" TileMode="Tile" Viewport="0,0,20,10" ViewportUnits="Absolute" Viewbox="0,0,20,10" ViewboxUnits="Absolute">
|
<VisualBrush x:Key="BeltBrushA" TileMode="Tile" Viewport="0,0,20,10" ViewportUnits="Absolute" Viewbox="0,0,20,10" ViewboxUnits="Absolute">
|
||||||
<VisualBrush.Transform>
|
<VisualBrush.Transform>
|
||||||
<TransformGroup>
|
<TransformGroup>
|
||||||
<TranslateTransform/>
|
<TranslateTransform/>
|
||||||
|
@ -22,6 +22,20 @@
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</VisualBrush.Visual>
|
</VisualBrush.Visual>
|
||||||
</VisualBrush>
|
</VisualBrush>
|
||||||
|
<VisualBrush x:Key="BeltBrushB" TileMode="Tile" Viewport="0,0,20,10" ViewportUnits="Absolute" Viewbox="0,0,20,10" ViewboxUnits="Absolute">
|
||||||
|
<VisualBrush.Transform>
|
||||||
|
<TransformGroup>
|
||||||
|
<TranslateTransform/>
|
||||||
|
</TransformGroup>
|
||||||
|
</VisualBrush.Transform>
|
||||||
|
<VisualBrush.Visual>
|
||||||
|
<Canvas>
|
||||||
|
<Rectangle Fill="#FFBFBFBF" Width="10" Height="10"/>
|
||||||
|
<Rectangle Fill="LightGray" Width="10" Height="10" Canvas.Left="10"/>
|
||||||
|
</Canvas>
|
||||||
|
</VisualBrush.Visual>
|
||||||
|
</VisualBrush>
|
||||||
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<UserControl.DataContext>
|
<UserControl.DataContext>
|
||||||
|
@ -38,59 +52,35 @@
|
||||||
<TranslateTransform/>
|
<TranslateTransform/>
|
||||||
</TransformGroup>
|
</TransformGroup>
|
||||||
</Canvas.RenderTransform>
|
</Canvas.RenderTransform>
|
||||||
<Rectangle x:Name="TransporteA" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.75}"
|
<Rectangle x:Name="TransporteA" Width="{Binding AnchoTransporte_oculto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
||||||
Fill="{StaticResource BeltBrush}"
|
Fill="{StaticResource BeltBrushA}"
|
||||||
/>
|
/>
|
||||||
<Rectangle x:Name="TransporteB" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.75}"
|
<Rectangle x:Name="TransporteB" Width="{Binding AnchoTransporte_oculto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
||||||
Fill="{StaticResource BeltBrush}"
|
Fill="{StaticResource BeltBrushB}"
|
||||||
Canvas.Top="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1.05}"
|
Canvas.Top="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1.05}"
|
||||||
Canvas.Left="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.25}"
|
Canvas.Left="{Binding AnchoRecto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
/>
|
/>
|
||||||
<Rectangle x:Name="GuiaSuperiorTop"
|
|
||||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.3}"
|
<uc:ThreeLinesControl x:Name="GuiaSuperior" AnchoRecto="{Binding AnchoRecto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue"
|
AnchoCentro="{Binding AnchoCentral, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Canvas.Top="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter},ConverterParameter=-1}"
|
Altura="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
|
AltoGuia="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
|
Canvas.Top="{Binding Distance, Converter={StaticResource MeterToPixelConverter},ConverterParameter=-1}"
|
||||||
/>
|
/>
|
||||||
<Rectangle x:Name="GuiaInternaA"
|
|
||||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.4}"
|
<uc:ThreeLinesControl x:Name="GuiaInferior" AnchoRecto="{Binding AnchoRecto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue"
|
AnchoCentro="{Binding AnchoCentral, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Canvas.Left="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.3}"
|
Altura="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
||||||
Canvas.Top="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.6}" RenderTransformOrigin="0.5,0.5"
|
AltoGuia="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}">
|
||||||
>
|
<Canvas.Top>
|
||||||
<Rectangle.RenderTransform>
|
<MultiBinding Converter="{StaticResource SumConverter}">
|
||||||
<RotateTransform Angle="17"/>
|
<Binding Path="Alto" Converter="{StaticResource MeterToPixelConverter}" ConverterParameter="1.0" />
|
||||||
</Rectangle.RenderTransform>
|
<Binding Path="Distance" Converter="{StaticResource MeterToPixelConverter}" ConverterParameter="1.0" />
|
||||||
</Rectangle>
|
</MultiBinding>
|
||||||
<Rectangle x:Name="GuiaInternaB"
|
</Canvas.Top>
|
||||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.4}"
|
</uc:ThreeLinesControl>
|
||||||
Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue"
|
|
||||||
Canvas.Left="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.3}"
|
|
||||||
Canvas.Top="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1.8}" RenderTransformOrigin="0.5,0.5"
|
|
||||||
>
|
|
||||||
<Rectangle.RenderTransform>
|
|
||||||
<RotateTransform Angle="15"/>
|
|
||||||
</Rectangle.RenderTransform>
|
|
||||||
</Rectangle>
|
|
||||||
<Rectangle x:Name="GuiaSuperiorBott"
|
|
||||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.3}"
|
|
||||||
Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue"
|
|
||||||
Canvas.Top="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=1}"
|
|
||||||
/>
|
|
||||||
<Rectangle x:Name="GuiaInferiorTop" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.3}"
|
|
||||||
Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}"
|
|
||||||
Canvas.Left="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.7}"
|
|
||||||
Canvas.Top="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.80}"
|
|
||||||
Fill="Blue"
|
|
||||||
/>
|
|
||||||
<Rectangle x:Name="GuiaInferiorBott" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.3}"
|
|
||||||
Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}"
|
|
||||||
Canvas.Left="{Binding Ancho, Converter={StaticResource MeterToPixelConverter},ConverterParameter=0.7}"
|
|
||||||
Canvas.Top="{Binding Alto, Converter={StaticResource MeterToPixelConverter},ConverterParameter=2.05}"
|
|
||||||
Fill="Blue"
|
|
||||||
/>
|
|
||||||
<uc:ThreeLinesControl AnchoRecto="50" AnchoCentro="70" Altura="25" AltoGuia="2"/>
|
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -111,12 +111,26 @@ namespace CtrEditor.ObjetosSim
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public float anchoCentral;
|
public float anchoCentral;
|
||||||
|
|
||||||
|
|
||||||
|
partial void OnAnchoRectoChanged(float value)
|
||||||
|
{
|
||||||
|
AnchoTransporte_oculto = anchoRecto + anchoCentral;
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnAnchoCentralChanged(float value)
|
||||||
|
{
|
||||||
|
AnchoTransporte_oculto = anchoRecto + anchoCentral;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public float anchoTransporte_oculto;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public float alto;
|
public float alto;
|
||||||
|
|
||||||
partial void OnAltoChanged(float value)
|
partial void OnAltoChanged(float value)
|
||||||
{
|
{
|
||||||
ActualizarGeometrias();
|
// ActualizarGeometrias();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
@ -166,8 +180,9 @@ namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
foreach (var transporte in SimGeometriaT)
|
foreach (var transporte in SimGeometriaT)
|
||||||
{
|
{
|
||||||
UpdateRectangle(transporte.Value, transporte.Key, Alto, Ancho, Angulo);
|
UpdateRectangle(transporte.Value, transporte.Key, Alto, AnchoTransporte_oculto, Angulo);
|
||||||
ActualizarStoryboards(transporte.Key);
|
ActualizarStoryboards(transporte.Key);
|
||||||
|
SetSpeed(transporte.Key);
|
||||||
}
|
}
|
||||||
foreach (var l in SimGeometriaG)
|
foreach (var l in SimGeometriaG)
|
||||||
UpdateOrCreateLine(l.Value, l.Key);
|
UpdateOrCreateLine(l.Value, l.Key);
|
||||||
|
@ -178,10 +193,11 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
public osTransporteGuiasUnion()
|
public osTransporteGuiasUnion()
|
||||||
{
|
{
|
||||||
Ancho = 1;
|
AnchoRecto = 0.5f;
|
||||||
|
AnchoCentral = 0.5f;
|
||||||
Alto = 0.10f;
|
Alto = 0.10f;
|
||||||
AltoGuia = 0.03f;
|
AltoGuia = 0.03f;
|
||||||
Distance = 0.01f;
|
Distance = 0.02f;
|
||||||
SimGeometriaT = new Dictionary<Rectangle, simTransporte>();
|
SimGeometriaT = new Dictionary<Rectangle, simTransporte>();
|
||||||
SimGeometriaG = new Dictionary<Rectangle, simGuia>();
|
SimGeometriaG = new Dictionary<Rectangle, simGuia>();
|
||||||
Storyboards = new Dictionary<Rectangle, Storyboard>();
|
Storyboards = new Dictionary<Rectangle, Storyboard>();
|
||||||
|
@ -235,22 +251,21 @@ namespace CtrEditor.ObjetosSim
|
||||||
// crear el objeto de simulacion
|
// crear el objeto de simulacion
|
||||||
if (_visualRepresentation is ucTransporteGuiasUnion uc)
|
if (_visualRepresentation is ucTransporteGuiasUnion uc)
|
||||||
{
|
{
|
||||||
var connector = new RectangleConnector(uc.Canvas, MeterToPixels(Alto/2));
|
|
||||||
connector.ConnectRectangles();
|
|
||||||
|
|
||||||
foreach (var child in uc.Canvas.Children)
|
foreach (var child in uc.Canvas.Children)
|
||||||
{
|
|
||||||
if (child is Rectangle rect)
|
if (child is Rectangle rect)
|
||||||
{
|
|
||||||
if (rect.Name.StartsWith("Transporte"))
|
if (rect.Name.StartsWith("Transporte"))
|
||||||
{
|
{
|
||||||
SimGeometriaT.Add(rect,AddRectangle(simulationManager, rect, Alto, Ancho, Angulo));
|
SimGeometriaT.Add(rect,AddRectangle(simulationManager, rect, Alto, AnchoTransporte_oculto, Angulo));
|
||||||
Storyboards.Add(rect,CrearAnimacionMultiStoryBoardTrasnporte(rect,false));
|
Storyboards.Add(rect,CrearAnimacionMultiStoryBoardTrasnporte(rect,false));
|
||||||
}
|
}
|
||||||
if (rect.Name.StartsWith("Guia"))
|
|
||||||
SimGeometriaG.Add(rect,AddLine(simulationManager, rect));
|
foreach (var child in uc.GuiaSuperior.Canvas.Children)
|
||||||
}
|
if (child is Rectangle rect)
|
||||||
}
|
SimGeometriaG.Add(rect, AddLine(simulationManager, rect));
|
||||||
|
|
||||||
|
foreach (var child in uc.GuiaInferior.Canvas.Children)
|
||||||
|
if (child is Rectangle rect)
|
||||||
|
SimGeometriaG.Add(rect, AddLine(simulationManager, rect));
|
||||||
|
|
||||||
TransportsDirection.Add(uc.TransporteA, new BoolReference(() => InvertirDireccionA, value => InvertirDireccionA = value));
|
TransportsDirection.Add(uc.TransporteA, new BoolReference(() => InvertirDireccionA, value => InvertirDireccionA = value));
|
||||||
TransportsDirection.Add(uc.TransporteB, new BoolReference(() => InvertirDireccionB, value => InvertirDireccionB = value));
|
TransportsDirection.Add(uc.TransporteB, new BoolReference(() => InvertirDireccionB, value => InvertirDireccionB = value));
|
||||||
|
@ -312,115 +327,6 @@ namespace CtrEditor.ObjetosSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RectangleConnector
|
|
||||||
{
|
|
||||||
private Canvas canvas;
|
|
||||||
private double maxDistance;
|
|
||||||
|
|
||||||
public RectangleConnector(Canvas canvas, double maxDistance)
|
|
||||||
{
|
|
||||||
this.canvas = canvas;
|
|
||||||
this.maxDistance = maxDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConnectRectangles()
|
|
||||||
{
|
|
||||||
var rectangles = canvas.Children.OfType<Rectangle>().Where(rect => rect.Name.StartsWith("Guia")).ToList();
|
|
||||||
|
|
||||||
foreach (var rect in rectangles)
|
|
||||||
{
|
|
||||||
var connections = GetConnectionPoints(rect);
|
|
||||||
foreach (var point in connections)
|
|
||||||
{
|
|
||||||
var closestPoint = GetClosestPoint(point, rectangles, rect);
|
|
||||||
if (closestPoint != null && GetDistance(point, closestPoint.Value) < maxDistance)
|
|
||||||
{
|
|
||||||
AdjustRectanglePosition(rect, point, closestPoint.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Point> GetConnectionPoints(Rectangle rect)
|
|
||||||
{
|
|
||||||
double width = rect.Width;
|
|
||||||
double height = rect.Height;
|
|
||||||
double angle = GetRotationAngle(rect);
|
|
||||||
|
|
||||||
// Puntos de conexión sin rotación
|
|
||||||
var points = new List<Point>
|
|
||||||
{
|
|
||||||
new Point(0, height / 2),
|
|
||||||
new Point(width, height / 2)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Aplicar rotación
|
|
||||||
var rotatedPoints = points.Select(p => RotatePoint(p, angle, new Point(width / 2, height / 2))).ToList();
|
|
||||||
return rotatedPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point RotatePoint(Point point, double angle, Point center)
|
|
||||||
{
|
|
||||||
double radians = angle * Math.PI / 180;
|
|
||||||
double cos = Math.Cos(radians);
|
|
||||||
double sin = Math.Sin(radians);
|
|
||||||
|
|
||||||
double dx = point.X - center.X;
|
|
||||||
double dy = point.Y - center.Y;
|
|
||||||
|
|
||||||
double x = center.X + (dx * cos - dy * sin);
|
|
||||||
double y = center.Y + (dx * sin + dy * cos);
|
|
||||||
|
|
||||||
return new Point(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private double GetRotationAngle(Rectangle rect)
|
|
||||||
{
|
|
||||||
var transform = rect.RenderTransform as RotateTransform;
|
|
||||||
return transform?.Angle ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point? GetClosestPoint(Point point, List<Rectangle> rectangles, Rectangle excludeRect)
|
|
||||||
{
|
|
||||||
Point? closestPoint = null;
|
|
||||||
double closestDistance = double.MaxValue;
|
|
||||||
|
|
||||||
foreach (var rect in rectangles)
|
|
||||||
{
|
|
||||||
if (rect == excludeRect) continue;
|
|
||||||
|
|
||||||
var points = GetConnectionPoints(rect);
|
|
||||||
foreach (var p in points)
|
|
||||||
{
|
|
||||||
double distance = GetDistance(point, p);
|
|
||||||
if (distance < closestDistance)
|
|
||||||
{
|
|
||||||
closestDistance = distance;
|
|
||||||
closestPoint = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return closestPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double GetDistance(Point p1, Point p2)
|
|
||||||
{
|
|
||||||
return Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AdjustRectanglePosition(Rectangle rect, Point currentPoint, Point targetPoint)
|
|
||||||
{
|
|
||||||
double offsetX = targetPoint.X - currentPoint.X;
|
|
||||||
double offsetY = targetPoint.Y - currentPoint.Y;
|
|
||||||
|
|
||||||
double newLeft = Canvas.GetLeft(rect) + offsetX;
|
|
||||||
double newTop = Canvas.GetTop(rect) + offsetY;
|
|
||||||
|
|
||||||
Canvas.SetLeft(rect, newLeft);
|
|
||||||
Canvas.SetTop(rect, newTop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class ucTransporteGuiasUnion : UserControl, IDataContainer
|
public partial class ucTransporteGuiasUnion : UserControl, IDataContainer
|
||||||
{
|
{
|
||||||
|
@ -443,7 +349,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
public void Resize(float width, float height)
|
public void Resize(float width, float height)
|
||||||
{
|
{
|
||||||
if (Datos is osTransporteGuiasUnion datos)
|
if (Datos is osTransporteGuiasUnion datos)
|
||||||
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
datos.AnchoRecto = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||||
}
|
}
|
||||||
public void Move(float LeftPixels, float TopPixels)
|
public void Move(float LeftPixels, float TopPixels)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,10 @@ namespace CtrEditor.ObjetosSim.UserControls
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ThreeLinesControl : UserControl
|
public partial class ThreeLinesControl : UserControl
|
||||||
{
|
{
|
||||||
|
private Rectangle _liz;
|
||||||
|
private Rectangle _lc;
|
||||||
|
private Rectangle _lde;
|
||||||
|
|
||||||
public ThreeLinesControl()
|
public ThreeLinesControl()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -18,7 +22,7 @@ namespace CtrEditor.ObjetosSim.UserControls
|
||||||
|
|
||||||
private void ThreeLinesControl_Loaded(object sender, RoutedEventArgs e)
|
private void ThreeLinesControl_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
CreateRectangles();
|
CreateOrUpdateRectangles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double AnchoRecto
|
public double AnchoRecto
|
||||||
|
@ -60,52 +64,76 @@ namespace CtrEditor.ObjetosSim.UserControls
|
||||||
private static void OnDimensionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnDimensionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var control = d as ThreeLinesControl;
|
var control = d as ThreeLinesControl;
|
||||||
control?.CreateRectangles();
|
control?.CreateOrUpdateRectangles();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateRectangles()
|
private void CreateOrUpdateRectangles()
|
||||||
|
{
|
||||||
|
if (_liz == null || _lc == null || _lde == null)
|
||||||
{
|
{
|
||||||
Canvas.Children.Clear();
|
|
||||||
|
|
||||||
// Crear Liz
|
// Crear Liz
|
||||||
var liz = new Rectangle
|
_liz = new Rectangle
|
||||||
{
|
{
|
||||||
Width = AnchoRecto,
|
Width = AnchoRecto,
|
||||||
Height = AltoGuia,
|
Height = AltoGuia,
|
||||||
Fill = Brushes.Blue
|
Fill = Brushes.Blue
|
||||||
};
|
};
|
||||||
Canvas.SetLeft(liz, 0);
|
Canvas.SetLeft(_liz, 0);
|
||||||
Canvas.SetTop(liz, -AltoGuia / 2);
|
Canvas.SetTop(_liz, -AltoGuia / 2);
|
||||||
Canvas.Children.Add(liz);
|
Canvas.Children.Add(_liz);
|
||||||
|
|
||||||
// Calcular la hipotenusa para Lc
|
|
||||||
double lcWidth = Math.Sqrt(Math.Pow(AnchoCentro, 2) + Math.Pow(Altura, 2));
|
|
||||||
|
|
||||||
// Crear Lc
|
// Crear Lc
|
||||||
var lc = new Rectangle
|
_lc = new Rectangle
|
||||||
{
|
{
|
||||||
Width = lcWidth,
|
Width = CalculateLcWidth(),
|
||||||
Height = AltoGuia,
|
Height = AltoGuia,
|
||||||
Fill = Brushes.Red,
|
Fill = Brushes.Red,
|
||||||
RenderTransformOrigin = new Point(0, 0.5)
|
RenderTransformOrigin = new Point(0, 0.5)
|
||||||
};
|
};
|
||||||
lc.RenderTransform = new RotateTransform(GetRotationAngle(AnchoCentro, Altura));
|
_lc.RenderTransform = new RotateTransform(GetRotationAngle(AnchoCentro, Altura));
|
||||||
Canvas.SetLeft(lc, AnchoRecto);
|
Canvas.SetLeft(_lc, AnchoRecto);
|
||||||
Canvas.SetTop(lc, -AltoGuia / 2);
|
Canvas.SetTop(_lc, -AltoGuia / 2);
|
||||||
Canvas.Children.Add(lc);
|
Canvas.Children.Add(_lc);
|
||||||
|
|
||||||
// Crear Lde
|
// Crear Lde
|
||||||
var lde = new Rectangle
|
_lde = new Rectangle
|
||||||
{
|
{
|
||||||
Width = AnchoRecto,
|
Width = AnchoRecto,
|
||||||
Height = AltoGuia,
|
Height = AltoGuia,
|
||||||
Fill = Brushes.Green
|
Fill = Brushes.Green
|
||||||
};
|
};
|
||||||
Canvas.SetLeft(lde, AnchoRecto + AnchoCentro);
|
Canvas.SetLeft(_lde, AnchoRecto + AnchoCentro);
|
||||||
Canvas.SetTop(lde, Altura - AltoGuia / 2);
|
Canvas.SetTop(_lde, Altura - AltoGuia / 2);
|
||||||
Canvas.Children.Add(lde);
|
Canvas.Children.Add(_lde);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Actualizar Liz
|
||||||
|
_liz.Width = AnchoRecto;
|
||||||
|
_liz.Height = AltoGuia;
|
||||||
|
Canvas.SetLeft(_liz, 0);
|
||||||
|
Canvas.SetTop(_liz, -AltoGuia / 2);
|
||||||
|
|
||||||
|
// Actualizar Lc
|
||||||
|
_lc.Width = CalculateLcWidth();
|
||||||
|
_lc.Height = AltoGuia;
|
||||||
|
_lc.RenderTransform = new RotateTransform(GetRotationAngle(AnchoCentro, Altura));
|
||||||
|
Canvas.SetLeft(_lc, AnchoRecto);
|
||||||
|
Canvas.SetTop(_lc, -AltoGuia / 2);
|
||||||
|
|
||||||
|
// Actualizar Lde
|
||||||
|
_lde.Width = AnchoRecto;
|
||||||
|
_lde.Height = AltoGuia;
|
||||||
|
Canvas.SetLeft(_lde, AnchoRecto + AnchoCentro);
|
||||||
|
Canvas.SetTop(_lde, Altura - AltoGuia / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Método auxiliar para calcular la hipotenusa
|
||||||
|
private double CalculateLcWidth()
|
||||||
|
{
|
||||||
|
return Math.Sqrt(Math.Pow(AnchoCentro, 2) + Math.Pow(Altura, 2));
|
||||||
|
}
|
||||||
|
|
||||||
private double GetRotationAngle(double anchoCentro, double altura)
|
private double GetRotationAngle(double anchoCentro, double altura)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,26 +1,17 @@
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Data;
|
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
||||||
using CtrEditor.Siemens;
|
using CtrEditor.Siemens;
|
||||||
using CtrEditor.Simulacion;
|
using CtrEditor.Simulacion;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using nkast.Aether.Physics2D.Common;
|
using nkast.Aether.Physics2D.Common;
|
||||||
using Siemens.Simatic.Simulation.Runtime;
|
using Siemens.Simatic.Simulation.Runtime;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Input;
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.Windows.Media.Animation;
|
using System.Windows.Media.Animation;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace CtrEditor.ObjetosSim
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
|
@ -243,7 +234,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(System.Windows.Shapes.Rectangle transporte, bool invertirDireccion)
|
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(Rectangle transporte, bool invertirDireccion)
|
||||||
{
|
{
|
||||||
if (_visualRepresentation == null) return null;
|
if (_visualRepresentation == null) return null;
|
||||||
if (transporte == null) return null;
|
if (transporte == null) return null;
|
||||||
|
@ -264,7 +255,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
return storyboard;
|
return storyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(Storyboard storyboard, System.Windows.Shapes.Rectangle transporte, bool invertirDireccion)
|
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(Storyboard storyboard, Rectangle transporte, bool invertirDireccion)
|
||||||
{
|
{
|
||||||
// Detener y eliminar el storyboard existente si hay uno
|
// Detener y eliminar el storyboard existente si hay uno
|
||||||
if (storyboard != null)
|
if (storyboard != null)
|
||||||
|
@ -287,7 +278,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
storyboard.SetSpeedRatio(Math.Abs(velocidadActual));
|
storyboard.SetSpeedRatio(Math.Abs(velocidadActual));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void CrearAnimacionStoryBoardTrasnporte(System.Windows.Shapes.Rectangle transporte, bool invertirDireccion)
|
protected void CrearAnimacionStoryBoardTrasnporte(Rectangle transporte, bool invertirDireccion)
|
||||||
{
|
{
|
||||||
_storyboard = CrearAnimacionMultiStoryBoardTrasnporte(_storyboard, transporte, invertirDireccion);
|
_storyboard = CrearAnimacionMultiStoryBoardTrasnporte(_storyboard, transporte, invertirDireccion);
|
||||||
}
|
}
|
||||||
|
@ -396,7 +387,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
public float CanvasGetTopinMeter()
|
public float CanvasGetTopinMeter()
|
||||||
{
|
{
|
||||||
if (_visualRepresentation != null)
|
if (_visualRepresentation != null)
|
||||||
return PixelToMeter.Instance.calc.PixelsToMeters((float)Canvas.GetTop(_visualRepresentation));
|
return PixelToMeter.Instance.calc.PixelsToMeters((float)System.Windows.Controls.Canvas.GetTop(_visualRepresentation));
|
||||||
else return 0f;
|
else return 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,12 +396,40 @@ namespace CtrEditor.ObjetosSim
|
||||||
return PixelToMeter.Instance.calc.PixelsToMeters(pixel);
|
return PixelToMeter.Instance.calc.PixelsToMeters(pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 PixelsToMeters(Vector2 pixel)
|
||||||
|
{
|
||||||
|
return new Vector2(PixelsToMeters(pixel.X),PixelsToMeters(pixel.Y));
|
||||||
|
}
|
||||||
|
|
||||||
public float MeterToPixels(float meter)
|
public float MeterToPixels(float meter)
|
||||||
{
|
{
|
||||||
return PixelToMeter.Instance.calc.MetersToPixels(meter);
|
return PixelToMeter.Instance.calc.MetersToPixels(meter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(System.Windows.Shapes.Rectangle rect)
|
public Vector2 MeterToPixels(Vector2 meter)
|
||||||
|
{
|
||||||
|
return new Vector2(MeterToPixels(meter.X), MeterToPixels(meter.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GeneralTransform GetTransformToRoot(Visual visual)
|
||||||
|
{
|
||||||
|
// Crear una transformación acumulativa inicial
|
||||||
|
GeneralTransformGroup transformGroup = new GeneralTransformGroup();
|
||||||
|
|
||||||
|
// Recorrer hacia arriba el árbol visual, acumulando las transformaciones
|
||||||
|
while (visual != null)
|
||||||
|
{
|
||||||
|
GeneralTransform transform = visual.TransformToAncestor(visual);
|
||||||
|
transformGroup.Children.Insert(0, transform);
|
||||||
|
visual = VisualTreeHelper.GetParent(visual) as Visual;
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(Rectangle rect)
|
||||||
{
|
{
|
||||||
if (rect != null)
|
if (rect != null)
|
||||||
{
|
{
|
||||||
|
@ -430,11 +449,22 @@ namespace CtrEditor.ObjetosSim
|
||||||
else return (new Vector2(0, 0), new Vector2(0, 0));
|
else return (new Vector2(0, 0), new Vector2(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public (Vector2 Start, Vector2 End) GetCenterLineVectors(System.Windows.Shapes.Rectangle rect)
|
public (Vector2 Start, Vector2 End) GetCenterLineVectors(Rectangle rect)
|
||||||
{
|
{
|
||||||
if (rect == null)
|
if (rect == null)
|
||||||
return (new Vector2(0, 0), new Vector2(0, 0));
|
return (new Vector2(0, 0), new Vector2(0, 0));
|
||||||
|
|
||||||
|
Vector2 start = new Vector2(0, 0);
|
||||||
|
Vector2 end = new Vector2(0, 0);
|
||||||
|
|
||||||
|
// Usar Dispatcher para asegurar la ejecución en el hilo correcto
|
||||||
|
_visualRepresentation?.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
// Asegúrate de que el control está en el árbol visual y actualizado
|
||||||
|
if (_visualRepresentation.IsLoaded && rect.IsLoaded)
|
||||||
|
{
|
||||||
|
_visualRepresentation.UpdateLayout();
|
||||||
|
|
||||||
var _canvasLeft = CanvasGetLeftinMeter();
|
var _canvasLeft = CanvasGetLeftinMeter();
|
||||||
var _canvasTop = CanvasGetTopinMeter();
|
var _canvasTop = CanvasGetTopinMeter();
|
||||||
|
|
||||||
|
@ -449,12 +479,15 @@ namespace CtrEditor.ObjetosSim
|
||||||
Point transformedEnd = transform.Transform(endLocal);
|
Point transformedEnd = transform.Transform(endLocal);
|
||||||
|
|
||||||
// Convierte a unidades de Farseer (metros en este caso)
|
// Convierte a unidades de Farseer (metros en este caso)
|
||||||
Vector2 start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop);
|
start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop);
|
||||||
Vector2 end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop);
|
end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (start, end);
|
return (start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Vector2 GetCurveCenterInMeter(float RadioExterno)
|
public Vector2 GetCurveCenterInMeter(float RadioExterno)
|
||||||
{
|
{
|
||||||
var _canvasLeft = CanvasGetLeftinMeter();
|
var _canvasLeft = CanvasGetLeftinMeter();
|
||||||
|
@ -468,7 +501,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
return new Vector2((float)centerX, (float)centerY);
|
return new Vector2((float)centerX, (float)centerY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 GetRectangleCenter(System.Windows.Shapes.Rectangle wpfRect)
|
public Vector2 GetRectangleCenter(Rectangle wpfRect)
|
||||||
{
|
{
|
||||||
var coords = GetRectangleCoordinatesInMeter(wpfRect);
|
var coords = GetRectangleCoordinatesInMeter(wpfRect);
|
||||||
|
|
||||||
|
@ -481,13 +514,13 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void UpdateRectangle(simTransporte simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
public void UpdateRectangle(simTransporte simRect, Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
||||||
{
|
{
|
||||||
if (simRect != null)
|
if (simRect != null)
|
||||||
simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRectangle(simBarrera simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
public void UpdateRectangle(simBarrera simRect, Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
||||||
{
|
{
|
||||||
if (simRect != null)
|
if (simRect != null)
|
||||||
simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
||||||
|
@ -503,20 +536,21 @@ namespace CtrEditor.ObjetosSim
|
||||||
return simulationManager.AddCurve(RadioInterno, RadioExterno, startAngle, endAngle, GetCurveCenterInMeter(RadioExterno));
|
return simulationManager.AddCurve(RadioInterno, RadioExterno, startAngle, endAngle, GetCurveCenterInMeter(RadioExterno));
|
||||||
}
|
}
|
||||||
|
|
||||||
public simTransporte AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
public simTransporte AddRectangle(SimulationManagerFP simulationManager, Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
||||||
{
|
{
|
||||||
return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public simBarrera AddBarrera(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo, bool detectarCuello)
|
public simBarrera AddBarrera(SimulationManagerFP simulationManager, Rectangle wpfRect, float Alto, float Ancho, float Angulo, bool detectarCuello)
|
||||||
{
|
{
|
||||||
return simulationManager.AddBarrera(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo, detectarCuello);
|
return simulationManager.AddBarrera(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo, detectarCuello);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateOrCreateLine(simGuia simGuia, System.Windows.Shapes.Rectangle wpfRect)
|
public void UpdateOrCreateLine(simGuia simGuia, Rectangle wpfRect)
|
||||||
{
|
{
|
||||||
if (simGuia != null)
|
if (simGuia != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
var coords = GetCenterLineVectors(wpfRect);
|
var coords = GetCenterLineVectors(wpfRect);
|
||||||
|
|
||||||
// Crear o actualizar simRectangle
|
// Crear o actualizar simRectangle
|
||||||
|
@ -524,7 +558,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public simGuia AddLine(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect)
|
public simGuia AddLine(SimulationManagerFP simulationManager, Rectangle wpfRect)
|
||||||
{
|
{
|
||||||
var coords = GetCenterLineVectors(wpfRect);
|
var coords = GetCenterLineVectors(wpfRect);
|
||||||
return simulationManager.AddLine(coords.Start, coords.End);
|
return simulationManager.AddLine(coords.Start, coords.End);
|
||||||
|
|
|
@ -5,6 +5,23 @@ using System.Windows;
|
||||||
|
|
||||||
namespace CtrEditor
|
namespace CtrEditor
|
||||||
{
|
{
|
||||||
|
public class SumConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (values.Length == 2 && values[0] is float value1 && values[1] is float value2)
|
||||||
|
{
|
||||||
|
return (double) (value1 + value2);
|
||||||
|
}
|
||||||
|
return DependencyProperty.UnsetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class VerticalPositionConverter : IValueConverter
|
public class VerticalPositionConverter : IValueConverter
|
||||||
{
|
{
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
|
Loading…
Reference in New Issue