Se añadió un nuevo método para verificar si un objeto visual es un hijo visual de otro, mejorando la gestión de transformaciones en la clase osBase. Además, se implementaron mejoras en la obtención de coordenadas de rectángulos, incluyendo validaciones para asegurar que los rectángulos estén cargados y disponibles antes de realizar transformaciones. Se mejoró la lógica de creación de geometría en ucTransporteTTop, asegurando que el layout esté actualizado y manejando excepciones para evitar fallos en la creación de simulaciones.

This commit is contained in:
Miguel 2025-06-22 16:44:19 +02:00
parent 58781c13a3
commit fefc0a700d
4 changed files with 235 additions and 25 deletions

26
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net8.0-windows8.0/CtrEditor.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/CtrEditor.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/CtrEditor.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/CtrEditor.sln"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -168,10 +168,56 @@ namespace CtrEditor.ObjetosSim
OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
if (_visualRepresentation is ucTransporteTTop uc) if (_visualRepresentation is ucTransporteTTop uc)
{
try
{
// Asegurar que el layout esté actualizado antes de crear la geometría
uc.UpdateLayout();
// Validar que el rectángulo esté disponible y tenga dimensiones válidas
if (uc.Transporte != null &&
(!double.IsNaN(uc.Transporte.ActualWidth) && uc.Transporte.ActualWidth > 0) ||
(!double.IsNaN(uc.Transporte.Width) && uc.Transporte.Width > 0))
{ {
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo); SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion); CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
} }
else
{
// Si el rectángulo no está listo, intentar después del próximo layout
uc.Dispatcher.BeginInvoke(new Action(() =>
{
if (uc.Transporte != null && simulationManager != null)
{
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
}
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
}
catch (Exception ex)
{
// Log del error para diagnóstico pero continuar sin fallar
System.Diagnostics.Debug.WriteLine($"Error al crear geometría de simulación: {ex.Message}");
// Intentar crear la geometría más tarde
uc.Dispatcher.BeginInvoke(new Action(() =>
{
try
{
if (uc.Transporte != null && simulationManager != null)
{
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
}
}
catch (Exception ex2)
{
System.Diagnostics.Debug.WriteLine($"Segundo intento falló: {ex2.Message}");
}
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
}
}
} }
public override void ucUnLoaded() public override void ucUnLoaded()
{ {

View File

@ -1364,14 +1364,66 @@ namespace CtrEditor.ObjetosSim
return transformGroup; return transformGroup;
} }
private static bool IsVisualChild(Visual child, Visual parent)
{
if (child == null || parent == null)
return false;
try
{
// Intentar obtener el ancestro común
var transform = child.TransformToAncestor(parent);
return transform != null;
}
catch (InvalidOperationException)
{
return false;
}
}
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(Rectangle rect) public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(Rectangle rect)
{ {
if (rect != null) if (rect == null)
{ return (new Vector2(0, 0), new Vector2(0, 0));
var _canvasLeft = CanvasGetLeftinMeter(); var _canvasLeft = CanvasGetLeftinMeter();
var _canvasTop = CanvasGetTopinMeter(); var _canvasTop = CanvasGetTopinMeter();
try
{
// Verificar que tanto el rectángulo como la representación visual estén cargados
if (!rect.IsLoaded || _visualRepresentation == null || !_visualRepresentation.IsLoaded)
{
// Fallback: usar las propiedades básicas de posición si la transformación no está disponible
float rectWidth = (float)rect.Width;
float rectHeight = (float)rect.Height;
if (double.IsNaN(rectWidth) || rectWidth == 0)
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
if (double.IsNaN(rectHeight) || rectHeight == 0)
rectHeight = Alto * PixelToMeter.Instance.calc.MetersToPixels(1);
return (new Vector2(_canvasLeft, _canvasTop),
new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth),
_canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectHeight)));
}
// Forzar actualización del layout
_visualRepresentation.UpdateLayout();
// Verificar que el rectángulo sea un descendiente visual de _visualRepresentation
if (!IsVisualChild(rect, _visualRepresentation))
{
// Fallback: usar las dimensiones básicas
float rectWidth = (float)rect.ActualWidth;
float rectHeight = (float)rect.ActualHeight;
return (new Vector2(_canvasLeft, _canvasTop),
new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth),
_canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectHeight)));
}
// Obtiene la transformada del objeto visual // Obtiene la transformada del objeto visual
GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation); GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation);
@ -1379,10 +1431,26 @@ namespace CtrEditor.ObjetosSim
Point topLeft = transform.Transform(new Point(0, 0)); Point topLeft = transform.Transform(new Point(0, 0));
Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight)); Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight));
return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop), return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft,
new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop)); PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop),
new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft,
PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop));
}
catch (InvalidOperationException)
{
// Fallback en caso de error de transformación
float rectWidth = (float)rect.ActualWidth;
float rectHeight = (float)rect.ActualHeight;
if (double.IsNaN(rectWidth) || rectWidth == 0)
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
if (double.IsNaN(rectHeight) || rectHeight == 0)
rectHeight = Alto * PixelToMeter.Instance.calc.MetersToPixels(1);
return (new Vector2(_canvasLeft, _canvasTop),
new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth),
_canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectHeight)));
} }
else return (new Vector2(0, 0), new Vector2(0, 0));
} }
public (Vector2 Start, Vector2 End) GetCenterLineVectors(Rectangle rect) public (Vector2 Start, Vector2 End) GetCenterLineVectors(Rectangle rect)
@ -1395,9 +1463,11 @@ namespace CtrEditor.ObjetosSim
// Usar Dispatcher para asegurar la ejecución en el hilo correcto // Usar Dispatcher para asegurar la ejecución en el hilo correcto
_visualRepresentation?.Dispatcher.Invoke(() => _visualRepresentation?.Dispatcher.Invoke(() =>
{
try
{ {
// Asegúrate de que el control está en el árbol visual y actualizado // Asegúrate de que el control está en el árbol visual y actualizado
if (_visualRepresentation.IsLoaded && rect.IsLoaded) if (_visualRepresentation.IsLoaded && rect.IsLoaded && IsVisualChild(rect, _visualRepresentation))
{ {
_visualRepresentation.UpdateLayout(); _visualRepresentation.UpdateLayout();
@ -1418,6 +1488,33 @@ namespace CtrEditor.ObjetosSim
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);
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);
} }
else
{
// Fallback: usar coordenadas básicas
var _canvasLeft = CanvasGetLeftinMeter();
var _canvasTop = CanvasGetTopinMeter();
float rectWidth = (float)rect.ActualWidth;
if (double.IsNaN(rectWidth) || rectWidth == 0)
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
start = new Vector2(_canvasLeft, _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
end = new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth), _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
}
}
catch (InvalidOperationException)
{
// Fallback en caso de error de transformación
var _canvasLeft = CanvasGetLeftinMeter();
var _canvasTop = CanvasGetTopinMeter();
float rectWidth = (float)rect.ActualWidth;
if (double.IsNaN(rectWidth) || rectWidth == 0)
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
start = new Vector2(_canvasLeft, _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
end = new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth), _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
}
}); });
return (start, end); return (start, end);