Refactor hydraulic components: Enhance UI elements and add flow indicators

- Updated ucHydPipe.xaml to improve visual representation with drop shadows and flow indicators.
- Modified ucHydPump.xaml to include a background ellipse and improved status indicators.
- Simplified ucHydTank.xaml by removing unnecessary sections and enhancing the fluid level display.
- Added a new method CopyFrom in osBase.cs to facilitate property copying between objects.
This commit is contained in:
Miguel 2025-09-11 14:52:45 +02:00
parent 1df7a24140
commit 1b21f86886
9 changed files with 1107 additions and 2766 deletions

View File

@ -120,7 +120,7 @@ namespace CtrEditor.HydraulicSimulator.TSNet
foreach (var node in tankNodes) foreach (var node in tankNodes)
{ {
var elevation = GetNodeElevation(node); var elevation = GetNodeElevation(node);
content.AppendLine($" {node.Name,-15}\t{elevation:F2} \t1.0 \t0.0 \t2.0 \t1.0 \t0 \t;"); content.AppendLine($" {node.Name,-15}\t{elevation:F2} \t1.0 \t0.0 \t2.0 \t1.0 \t0 \t");
} }
content.AppendLine(); content.AppendLine();
@ -158,8 +158,9 @@ namespace CtrEditor.HydraulicSimulator.TSNet
{ {
foreach (var element in branch.Elements.OfType<PumpHQ>()) foreach (var element in branch.Elements.OfType<PumpHQ>())
{ {
var id = $"PUMP{pumpId++}"; var id = $"PUMP{pumpId}";
content.AppendLine($" {id,-15}\t{branch.N1,-15}\t{branch.N2,-15}\tHEAD CURVE{pumpId}"); content.AppendLine($" {id,-15}\t{branch.N1,-15}\t{branch.N2,-15}\tHEAD CURVE{pumpId}");
pumpId++;
} }
} }

View File

@ -2046,6 +2046,29 @@ namespace CtrEditor
#endregion #endregion
#region Hydraulic Network Management
/// <summary>
/// Invalidates the hydraulic network to force recalculation
/// </summary>
public void InvalidateHydraulicNetwork()
{
try
{
if (hydraulicSimulationManager != null)
{
hydraulicSimulationManager.InvalidateNetwork();
Debug.WriteLine("Red hidráulica invalidada y marcada para recálculo");
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error al invalidar red hidráulica: {ex.Message}");
}
}
#endregion
#region MCP Server Management #region MCP Server Management
/// <summary> /// <summary>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,7 @@
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.DataContext> <!-- DataContext se establece desde el objeto padre -->
<vm:osHydPipe Ancho="2.0" Alto="0.2"/>
</UserControl.DataContext>
<Canvas RenderTransformOrigin="0,0"> <Canvas RenderTransformOrigin="0,0">
<Canvas.RenderTransform> <Canvas.RenderTransform>
@ -29,9 +27,13 @@
Stroke="Black" Stroke="Black"
StrokeThickness="2" StrokeThickness="2"
RadiusX="5" RadiusX="5"
RadiusY="5"/> RadiusY="5">
<Rectangle.Effect>
<DropShadowEffect Color="Gray" ShadowDepth="2" Opacity="0.3"/>
</Rectangle.Effect>
</Rectangle>
<!-- Etiqueta con Viewbox para escalado --> <!-- Etiqueta con nombre de la tubería -->
<Viewbox Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" <Viewbox Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Stretch="Uniform"> Stretch="Uniform">
@ -46,17 +48,43 @@
<!-- Indicador de flujo --> <!-- Indicador de flujo -->
<Border x:Name="FlowIndicator" <Border x:Name="FlowIndicator"
Background="Yellow" Background="#AA000000"
CornerRadius="2" CornerRadius="3"
Visibility="Collapsed" Padding="3,1"
Canvas.Top="-20" Canvas.Top="-25"
Canvas.Left="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.5}"> Canvas.Left="5">
<TextBlock x:Name="FlowText" <StackPanel Orientation="Horizontal">
Text="0.00" <TextBlock Text="{Binding CurrentFlowLMin, StringFormat='{}{0:F1} L/min'}"
FontSize="6" FontSize="8"
Foreground="Black" Foreground="White"
Margin="2"/> Margin="0,0,3,0"/>
<TextBlock Text="{Binding PressureDropBar, StringFormat='{}{0:F2} bar'}"
FontSize="8"
Foreground="Yellow"/>
</StackPanel>
</Border> </Border>
<!-- Indicador de dirección de flujo -->
<Path x:Name="FlowArrow"
Stroke="Yellow"
StrokeThickness="2"
Fill="Yellow"
Visibility="{Binding HasFlow, Converter={StaticResource BooleanToVisibilityConverter}}">
<Path.Data>
<GeometryGroup>
<LineGeometry StartPoint="10,0" EndPoint="30,0"/>
<PathGeometry>
<PathFigure StartPoint="25,-5">
<LineSegment Point="35,0"/>
<LineSegment Point="25,5"/>
</PathFigure>
</PathGeometry>
</GeometryGroup>
</Path.Data>
<Path.RenderTransform>
<TranslateTransform X="10" Y="{Binding Alto, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.5}"/>
</Path.RenderTransform>
</Path>
</Canvas> </Canvas>
</UserControl> </UserControl>

View File

@ -7,7 +7,7 @@
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d"> mc:Ignorable="d">
<!-- DataContext se establece desde el objeto padre, no aquí --> <!-- DataContext se establece desde el objeto padre -->
<Grid RenderTransformOrigin="0,0"> <Grid RenderTransformOrigin="0,0">
<Grid.RenderTransform> <Grid.RenderTransform>
@ -22,18 +22,47 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Imagen de la bomba --> <!-- Imagen de la bomba -->
<Image Grid.Row="0" Source="{Binding ImageSource_oculta}" <Grid Grid.Row="0">
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}" <!-- Círculo de fondo para la bomba -->
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}" <Ellipse Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Stretch="Uniform"/> Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Fill="{Binding ColorButton_oculto}"
Stroke="Black"
StrokeThickness="2">
<Ellipse.Effect>
<DropShadowEffect Color="Gray" ShadowDepth="2" Opacity="0.5"/>
</Ellipse.Effect>
</Ellipse>
<!-- Imagen de la bomba si está disponible -->
<Image Source="{Binding ImageSource_oculta}"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.8}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.8}"
Stretch="Uniform"/>
<!-- Indicador visual de estado si no hay imagen -->
<Grid>
<TextBlock Text="P" FontSize="18" FontWeight="Bold"
Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<!-- Indicador de funcionamiento -->
<Ellipse Width="8" Height="8"
Fill="{Binding IsRunning, Converter={StaticResource BoolToColorConverter}}"
HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0,2,2,0"/>
</Grid>
</Grid>
<!-- Panel de información con presión y caudal --> <!-- Panel de información con presión y caudal -->
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center"> <Border Grid.Row="1" Background="#AA000000" CornerRadius="3" Padding="3" Margin="0,2,0,0">
<TextBlock Text="{Binding CurrentPressureBar, StringFormat='{}{0:F1} bar'}" <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
Foreground="White" Background="Blue" Padding="2" Margin="1" FontSize="8"/> <TextBlock Text="{Binding CurrentPressureBar, StringFormat='{}{0:F1} bar'}"
<TextBlock Text="{Binding CurrentFlowLMin, StringFormat='{}{0:F1} L/min'}" Foreground="White" Background="Blue" Padding="2" Margin="1" FontSize="8"/>
Foreground="White" Background="Green" Padding="2" Margin="1" FontSize="8"/> <TextBlock Text="{Binding CurrentFlowLMin, StringFormat='{}{0:F1} L/min'}"
</StackPanel> Foreground="White" Background="Green" Padding="2" Margin="1" FontSize="8"/>
<TextBlock Text="{Binding CurrentHead, StringFormat='{}{0:F1} m'}"
Foreground="White" Background="Orange" Padding="2" Margin="1" FontSize="8"/>
</StackPanel>
</Border>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -7,10 +7,7 @@
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d"> mc:Ignorable="d">
<!-- DataContext se establece desde el objeto padre, no aquí --> <!-- DataContext se establece desde el objeto padre -->
<UserControl.DataContext>
<vm:osHydTank />
</UserControl.DataContext>
<Canvas RenderTransformOrigin="0,0"> <Canvas RenderTransformOrigin="0,0">
<Canvas.RenderTransform> <Canvas.RenderTransform>
@ -22,18 +19,21 @@
</TransformGroup> </TransformGroup>
</Canvas.RenderTransform> </Canvas.RenderTransform>
<!-- Contenedor principal del tanque con diseño mejorado --> <!-- Contenedor principal del tanque -->
<Grid Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}" <Grid Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.4}"> Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.4}">
<!-- Fondo del tanque (contenedor vacío) con diseño 3D --> <!-- Fondo del tanque (contenedor vacío) -->
<Rectangle x:Name="rectTankContainer" <Rectangle x:Name="rectTankContainer"
Fill="#FFE6E6E6" Fill="#FFE6E6E6"
Stroke="#FF606060" Stroke="#FF606060"
StrokeThickness="3" StrokeThickness="3"
RadiusX="8" RadiusX="8"
RadiusY="8" RadiusY="8">
Effect="{StaticResource DropShadowEffect}"/> <Rectangle.Effect>
<DropShadowEffect Color="Gray" ShadowDepth="3" Opacity="0.5"/>
</Rectangle.Effect>
</Rectangle>
<!-- Marco interno del tanque --> <!-- Marco interno del tanque -->
<Rectangle Fill="Transparent" <Rectangle Fill="Transparent"
@ -43,132 +43,40 @@
RadiusY="6" RadiusY="6"
Margin="6"/> Margin="6"/>
<!-- Sistema de tres secciones (solo si está habilitado) --> <!-- Nivel del líquido -->
<Grid x:Name="ThreeSectionContainer" <Rectangle x:Name="rectFluidLevel"
Margin="8" Fill="{Binding ColorButton_oculto}"
Visibility="{Binding EnableThreeSection, Converter={StaticResource BooleanToVisibilityConverter}}"> Stroke="DarkBlue"
StrokeThickness="1.5"
<!-- Sección secundaria (abajo) --> RadiusX="4"
<Rectangle x:Name="rectSecondaryLevel" RadiusY="4"
Fill="{Binding SecondaryLevelColor}" VerticalAlignment="Bottom"
Stroke="#FF1E90FF" Opacity="0.85"
StrokeThickness="1.5" Margin="8">
RadiusX="4" <Rectangle.Height>
RadiusY="4" <MultiBinding Converter="{StaticResource TankLevelToHeightConverter}">
VerticalAlignment="Bottom" <Binding Path="FillPercentage"/>
Opacity="0.85"> <Binding Path="Tamano" Converter="{StaticResource MeterToPixelConverter}" ConverterParameter="1.2"/>
<Rectangle.Height> </MultiBinding>
<MultiBinding Converter="{StaticResource TankLevelToHeightConverter}"> </Rectangle.Height>
<Binding Path="SecondaryPercentage"/> </Rectangle>
<Binding Path="Tamano"/>
<Binding Source="0.33"/>
</MultiBinding>
</Rectangle.Height>
</Rectangle>
<!-- Sección de mezcla (medio) -->
<Rectangle x:Name="rectMixLevel"
Fill="{Binding MixLevelColor}"
Stroke="#FFFF6347"
StrokeThickness="1.5"
RadiusX="4"
RadiusY="4"
VerticalAlignment="Bottom"
Opacity="0.85">
<Rectangle.Height>
<MultiBinding Converter="{StaticResource TankLevelToHeightConverter}">
<Binding Path="PrimaryPercentage"/>
<Binding Path="Tamano"/>
<Binding Source="0.33"/>
</MultiBinding>
</Rectangle.Height>
<Rectangle.Margin>
<MultiBinding Converter="{StaticResource TankSectionMarginConverter}">
<Binding Path="SecondaryPercentage"/>
<Binding Path="Tamano"/>
<Binding Source="0.33"/>
</MultiBinding>
</Rectangle.Margin>
</Rectangle>
<!-- Etiquetas de sección -->
<Canvas>
<!-- Etiqueta sección secundaria -->
<Border Background="#AA1E90FF" CornerRadius="2" Padding="2,1"
Canvas.Left="2" Canvas.Bottom="2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Sec:" Foreground="White" FontSize="6" FontWeight="Bold"/>
<TextBlock Text="{Binding SecondaryPercentage, StringFormat='{}{0:F0}%'}"
Foreground="White" FontSize="6" Margin="1,0,0,0"/>
<TextBlock Text="{Binding SecondaryVolumeL, StringFormat=' ({0:F0}L)'}"
Foreground="White" FontSize="5" Opacity="0.9"/>
</StackPanel>
</Border>
<!-- Etiqueta sección primaria -->
<Border Background="#AAFF6347" CornerRadius="2" Padding="2,1"
Canvas.Right="2" Canvas.Top="2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Pri:" Foreground="White" FontSize="6" FontWeight="Bold"/>
<TextBlock Text="{Binding PrimaryPercentage, StringFormat='{}{0:F0}%'}"
Foreground="White" FontSize="6" Margin="1,0,0,0"/>
<TextBlock Text="{Binding PrimaryVolumeL, StringFormat=' ({0:F0}L)'}"
Foreground="White" FontSize="5" Opacity="0.9"/>
</StackPanel>
</Border>
</Canvas>
</Grid>
<!-- Sistema de una sección (clásico) -->
<Grid x:Name="SingleSectionContainer"
Margin="8"
Visibility="{Binding EnableThreeSection, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<!-- Nivel del líquido tradicional -->
<Rectangle x:Name="rectFluidLevel"
Fill="{Binding LevelColor}"
Stroke="{Binding LevelBorderColor}"
StrokeThickness="1.5"
RadiusX="4"
RadiusY="4"
VerticalAlignment="Bottom"
Opacity="0.85">
<Rectangle.Height>
<MultiBinding Converter="{StaticResource TankLevelToHeightConverter}">
<Binding Path="FillPercentage"/>
<Binding Path="Tamano"/>
<Binding Source="1.0"/>
</MultiBinding>
</Rectangle.Height>
</Rectangle>
</Grid>
<!-- Información central del tanque --> <!-- Información central del tanque -->
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<!-- Nivel total y volumen -->
<Border Background="#AA000000" CornerRadius="4" Padding="6,4"> <Border Background="#AA000000" CornerRadius="4" Padding="6,4">
<StackPanel HorizontalAlignment="Center"> <StackPanel HorizontalAlignment="Center">
<!-- Porcentaje principal --> <!-- Nivel y porcentaje -->
<TextBlock Text="{Binding FillPercentage, StringFormat='{}{0:F0}%'}" <TextBlock Foreground="White" FontSize="10" HorizontalAlignment="Center">
HorizontalAlignment="Center" <TextBlock.Text>
Foreground="White" <MultiBinding StringFormat="{}{0:F2}m ({1:F0}%)">
FontWeight="Bold" <Binding Path="CurrentLevel"/>
FontSize="14"/> <Binding Path="FillPercentage"/>
</MultiBinding>
<!-- Volumen actual --> </TextBlock.Text>
<TextBlock Text="{Binding CurrentVolumeL, StringFormat='{}{0:F0} L'}" </TextBlock>
HorizontalAlignment="Center" <!-- Volumen -->
Foreground="LightCyan" <TextBlock Text="{Binding CurrentVolume, StringFormat='{}{0:F0}L'}"
FontSize="8" Foreground="LightCyan" FontSize="8" HorizontalAlignment="Center"/>
Margin="0,1,0,0"/>
<!-- Nivel sobre el mar -->
<TextBlock Text="{Binding CurrentLevelM, StringFormat='⌂ {0:F2} m'}"
HorizontalAlignment="Center"
Foreground="LightGreen"
FontSize="7"
Margin="0,1,0,0"/>
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>
@ -178,29 +86,18 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Nombre del tanque -->
<!-- Tipo de fluido actual --> <Border Grid.Row="0" Background="#FF4169E1" CornerRadius="3" Padding="3,2">
<Border Grid.Row="1" Background="#FF006400" CornerRadius="3" Padding="3,2" Margin="0,2,0,0"> <TextBlock Text="{Binding Nombre}"
<TextBlock Text="{Binding CurrentFluidDescription}" Foreground="White" FontSize="8" FontWeight="Bold"/>
Foreground="White"
FontSize="7"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis"
MaxWidth="60"/>
</Border> </Border>
<!-- Estado de mezcla --> <!-- Tipo de fluido -->
<Border Grid.Row="2" Background="#FF8B4513" CornerRadius="3" Padding="3,2" Margin="0,2,0,0" <Border Grid.Row="1" Background="#FF006400" CornerRadius="3" Padding="3,2" Margin="0,2,0,0">
Visibility="{Binding EnableThreeSection, Converter={StaticResource BooleanToVisibilityConverter}}"> <TextBlock Text="{Binding FluidDescription}"
<TextBlock Text="{Binding MixingState}" Foreground="White" FontSize="7" FontWeight="Bold"/>
Foreground="White"
FontSize="6"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis"
MaxWidth="60"/>
</Border> </Border>
</Grid> </Grid>
</Grid> </Grid>
@ -209,69 +106,15 @@
<Grid Canvas.Top="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.5}" <Grid Canvas.Top="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.5}"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"> Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}">
<!-- Fondo del panel con gradiente --> <Border Background="#AA000000" CornerRadius="5" Margin="0,4,0,0" Padding="4">
<Border CornerRadius="5" Margin="0,4,0,0" Padding="4">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center"> <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<!-- Fila 1: Presión y Flujo -->
<!-- Fila 1: Presión y Nivel absoluto -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,2"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,2">
<!-- Presión actual --> <TextBlock Text="{Binding CurrentPressure, StringFormat='{}{0:F2} bar'}"
<Border Background="#FF1E90FF" CornerRadius="3" Padding="4,3" Margin="2"> Foreground="White" Background="Blue" Padding="2" Margin="1" FontSize="7"/>
<StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding CurrentFlow, StringFormat='{}{0:F3} m³/s'}"
<TextBlock Text="⚡" Foreground="White" FontSize="9" FontWeight="Bold"/> Foreground="White" Background="Green" Padding="2" Margin="1" FontSize="7"/>
<TextBlock Text="{Binding CurrentPressure, StringFormat='{}{0:F2}'}"
Foreground="White" FontSize="8" FontWeight="SemiBold" Margin="2,0,0,0"/>
<TextBlock Text="bar" Foreground="LightCyan" FontSize="7" Opacity="0.9" Margin="1,0,0,0"/>
</StackPanel>
</Border>
<!-- Nivel absoluto -->
<Border Background="#FF32CD32" CornerRadius="3" Padding="4,3" Margin="2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="🌊" Foreground="White" FontSize="9" FontWeight="Bold"/>
<TextBlock Text="{Binding CurrentLevelM, StringFormat='{}{0:F3}'}"
Foreground="White" FontSize="8" FontWeight="SemiBold" Margin="2,0,0,0"/>
<TextBlock Text="m" Foreground="LightGreen" FontSize="7" Opacity="0.9" Margin="1,0,0,0"/>
</StackPanel>
</Border>
</StackPanel> </StackPanel>
<!-- Fila 2: Flujo neto -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,2">
<!-- Flujo neto -->
<Border Background="{Binding FlowBalanceColor}" CornerRadius="3" Padding="4,3" Margin="2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="⇄" Foreground="White" FontSize="9" FontWeight="Bold"/>
<TextBlock Text="{Binding NetFlow, StringFormat='{}{0:F1}'}"
Foreground="White" FontSize="8" FontWeight="SemiBold" Margin="2,0,0,0"/>
<TextBlock Text="L/min" Foreground="White" FontSize="6" Opacity="0.9" Margin="1,0,0,0"/>
</StackPanel>
</Border>
</StackPanel>
<!-- Fila 3: Volumen secundario y mix (simplificado) -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,2">
<!-- Volumen secundario -->
<Border Background="#AA1E90FF" CornerRadius="3" Padding="3,2" Margin="1">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Sec:" Foreground="White" FontSize="7" FontWeight="Bold"/>
<TextBlock Text="{Binding SecondaryVolumeL, StringFormat='{}{0:F0}L'}"
Foreground="White" FontSize="7" Margin="1,0,0,0"/>
</StackPanel>
</Border>
<!-- Volumen de mezcla -->
<Border Background="#AA8B4513" CornerRadius="3" Padding="3,2" Margin="1">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Mix:" Foreground="White" FontSize="7" FontWeight="Bold"/>
<TextBlock Text="{Binding MixingVolumeL, StringFormat='{}{0:F0}L'}"
Foreground="White" FontSize="7" Margin="1,0,0,0"/>
</StackPanel>
</Border>
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@ -1867,6 +1867,28 @@ namespace CtrEditor.ObjetosSim
System.Diagnostics.Debug.WriteLine($"[Dimensions] Cleared ALL stored dimensions"); System.Diagnostics.Debug.WriteLine($"[Dimensions] Cleared ALL stored dimensions");
} }
/// <summary>
/// Copia propiedades comunes desde otro objeto osBase
/// </summary>
/// <param name="source">Objeto fuente para copiar</param>
public virtual void CopyFrom(osBase source)
{
if (source == null) return;
try
{
// Copiar propiedades básicas comunes que están disponibles en osBase
Nombre = source.Nombre;
// Nota: X, Y, Width, Height no están definidas en osBase base
// Las clases derivadas pueden override este método para copiar sus propiedades específicas
}
catch (Exception ex)
{
Debug.WriteLine($"Error en CopyFrom: {ex.Message}");
}
}
} }
public class UniqueId public class UniqueId
{ {