Se añadió la capacidad de gestionar datos de imágenes en la clase DatosDeTrabajo, permitiendo la carga de datos desde archivos JSON y la integración con MainViewModel. Se implementó un nuevo método para establecer el ViewModel principal y se mejoró la lógica de renombrado de imágenes en la interfaz de usuario, incluyendo un comando para renombrar imágenes desde el contexto del ListBox. Además, se incorporó un convertidor para mostrar nombres de imágenes personalizados en la interfaz.
This commit is contained in:
parent
9b710fcb00
commit
909e438f5b
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace CtrEditor.Converters
|
||||
{
|
||||
public class ImageDisplayNameConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is string imageName)
|
||||
{
|
||||
// Buscar el MainViewModel en el Application.Current.MainWindow.DataContext
|
||||
if (Application.Current?.MainWindow?.DataContext is MainViewModel viewModel)
|
||||
{
|
||||
return viewModel.GetImageDisplayName(imageName);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ namespace CtrEditor
|
|||
public class DatosDeTrabajo
|
||||
{
|
||||
public Dictionary<string, string> Imagenes { get; private set; }
|
||||
private MainViewModel _mainViewModel;
|
||||
|
||||
public DatosDeTrabajo()
|
||||
{
|
||||
|
@ -18,6 +19,11 @@ namespace CtrEditor
|
|||
CargarImagenes(); // Inicializar la carga de imágenes basada en el directorio persistente
|
||||
}
|
||||
|
||||
public void SetMainViewModel(MainViewModel mainViewModel)
|
||||
{
|
||||
_mainViewModel = mainViewModel;
|
||||
}
|
||||
|
||||
public string ObtenerPathImagenConExtension(string key, string extension)
|
||||
{
|
||||
if (Imagenes.TryGetValue(key, out string imagePath))
|
||||
|
@ -51,6 +57,34 @@ namespace CtrEditor
|
|||
Imagenes[nombreArchivo] = archivo;
|
||||
}
|
||||
}
|
||||
|
||||
// Cargar datos de imágenes existentes desde archivos JSON
|
||||
if (_mainViewModel != null)
|
||||
{
|
||||
CargarDatosImagenesExistentes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CargarDatosImagenesExistentes()
|
||||
{
|
||||
foreach (var imageName in Imagenes.Keys)
|
||||
{
|
||||
string jsonPath = ObtenerPathImagenConExtension(imageName, ".json");
|
||||
if (!string.IsNullOrEmpty(jsonPath) && File.Exists(jsonPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Solo cargamos los datos de imagen si existe el archivo JSON
|
||||
// El StateSerializer se encargará de cargar los datos completos
|
||||
_mainViewModel.GetOrCreateImageData(imageName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log del error pero no fallar la carga completa
|
||||
System.Diagnostics.Debug.WriteLine($"Error al pre-cargar datos de imagen {imageName}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,12 @@ namespace CtrEditor
|
|||
[ObservableProperty]
|
||||
public ObservableCollection<TipoSimulable> listaOsBase;
|
||||
|
||||
// Diccionario para almacenar datos expandidos de imágenes
|
||||
public Dictionary<string, Models.ImageData> _imageDataDictionary = new Dictionary<string, Models.ImageData>();
|
||||
|
||||
// Comando para renombrar imagen
|
||||
public ICommand RenameImageCommand { get; private set; }
|
||||
|
||||
public ICommand StartSimulationCommand { get; }
|
||||
public ICommand StopSimulationCommand { get; }
|
||||
public ICommand ItemDoubleClickCommand { get; private set; }
|
||||
|
@ -383,6 +389,7 @@ namespace CtrEditor
|
|||
TBMultiPageAnalizeCommand = new RelayCommand(MultiPageAnalizeCommand);
|
||||
TBMultiPageMatrixCommand = new RelayCommand(MultiPageMatrixCommand);
|
||||
TBLibraryManagerCommand = new RelayCommand(ShowLibraryManager);
|
||||
RenameImageCommand = new RelayCommand<string>(RenameImage);
|
||||
|
||||
stopwatch_Sim = new Stopwatch();
|
||||
stopwatch_Sim.Start();
|
||||
|
@ -398,6 +405,68 @@ namespace CtrEditor
|
|||
|
||||
_stateManager = new StateManager(EstadoPersistente.Instance.directorio, this);
|
||||
_stateSerializer = new StateSerializer(this, datosDeTrabajo, simulationManager);
|
||||
|
||||
// Conectar DatosDeTrabajo con este ViewModel para el escaneo de imágenes
|
||||
datosDeTrabajo.SetMainViewModel(this);
|
||||
}
|
||||
|
||||
// Métodos para manejo de datos de imágenes
|
||||
private void RenameImage(string imageName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(imageName)) return;
|
||||
|
||||
var imageData = GetOrCreateImageData(imageName);
|
||||
var currentCustomName = imageData.CustomName;
|
||||
|
||||
var dialog = new PopUps.RenameImageWindow(imageName, currentCustomName);
|
||||
dialog.Owner = MainWindow;
|
||||
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
string newName = dialog.NewImageName?.Trim() ?? string.Empty;
|
||||
|
||||
if (newName != currentCustomName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(newName))
|
||||
{
|
||||
// Si el nuevo nombre está vacío, removemos la entrada personalizada
|
||||
imageData.CustomName = string.Empty;
|
||||
if (string.IsNullOrEmpty(imageData.CustomName) && imageData.Tags.Count == 0)
|
||||
{
|
||||
_imageDataDictionary.Remove(imageName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
imageData.CustomName = newName;
|
||||
}
|
||||
|
||||
// Forzar actualización del UI usando CollectionViewSource
|
||||
var collectionView = System.Windows.Data.CollectionViewSource.GetDefaultView(ListaImagenes);
|
||||
collectionView?.Refresh();
|
||||
|
||||
HasUnsavedChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetImageDisplayName(string imageName)
|
||||
{
|
||||
if (_imageDataDictionary.TryGetValue(imageName, out var imageData))
|
||||
{
|
||||
return imageData.DisplayName;
|
||||
}
|
||||
return imageName;
|
||||
}
|
||||
|
||||
public Models.ImageData GetOrCreateImageData(string imageName)
|
||||
{
|
||||
if (!_imageDataDictionary.TryGetValue(imageName, out var imageData))
|
||||
{
|
||||
imageData = new Models.ImageData(imageName);
|
||||
_imageDataDictionary[imageName] = imageData;
|
||||
}
|
||||
return imageData;
|
||||
}
|
||||
|
||||
private void OnVisFilterChanged(osVisFilterViewModel filter) // Changed signature to accept viewmodel directly
|
||||
|
@ -1202,6 +1271,13 @@ namespace CtrEditor
|
|||
|
||||
// Nueva propiedad para almacenar los datos locales de objetos globales
|
||||
public ObservableCollection<DatosLocales>? DatosLocalesObjetos { get; set; }
|
||||
|
||||
// Diccionario para almacenar datos expandidos de imágenes
|
||||
public Dictionary<string, Models.ImageData>? ImageDataDictionary { get; set; }
|
||||
|
||||
// Compatibilidad con versiones anteriores - OBSOLETO
|
||||
[System.Obsolete("Use ImageDataDictionary instead")]
|
||||
public Dictionary<string, string>? ImageCustomNames { get; set; }
|
||||
}
|
||||
|
||||
public class TipoSimulable
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
xmlns:local="clr-namespace:CtrEditor"
|
||||
xmlns:controls="clr-namespace:CtrEditor.Controls"
|
||||
xmlns:uc="clr-namespace:CtrEditor.ObjetosSim.UserControls"
|
||||
xmlns:converters="clr-namespace:CtrEditor.Converters"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:ObjetosSim="clr-namespace:CtrEditor.ObjetosSim"
|
||||
|
@ -48,6 +49,9 @@
|
|||
<!-- Converter for PLC Connect/Disconnect image -->
|
||||
<local:ConnectStateToImageConverter x:Key="ConnectStateToImageConverter" />
|
||||
|
||||
<!-- Converter for Image Display Names -->
|
||||
<converters:ImageDisplayNameConverter x:Key="ImageDisplayNameConverter" />
|
||||
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
|
@ -87,7 +91,18 @@
|
|||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding ListaImagenes}"
|
||||
SelectedItem="{Binding SelectedImage}" />
|
||||
SelectedItem="{Binding SelectedImage}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={StaticResource ImageDisplayNameConverter}}"/>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
<ListBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Renombrar" Command="{Binding RenameImageCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
|
||||
</ContextMenu>
|
||||
</ListBox.ContextMenu>
|
||||
</ListBox>
|
||||
<ListBox x:Name="ListaFunciones" Grid.Row="1" Margin="5" ItemsSource="{Binding ListaOsBase}"
|
||||
DisplayMemberPath="Nombre" SelectedItem="{Binding SelectedItem}">
|
||||
<i:Interaction.Triggers>
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CtrEditor.Models
|
||||
{
|
||||
public class ImageData : INotifyPropertyChanged
|
||||
{
|
||||
private string _customName;
|
||||
private List<string> _tags;
|
||||
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string CustomName
|
||||
{
|
||||
get => _customName;
|
||||
set
|
||||
{
|
||||
_customName = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> Tags
|
||||
{
|
||||
get => _tags ?? new List<string>();
|
||||
set
|
||||
{
|
||||
_tags = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName => !string.IsNullOrEmpty(CustomName) ? CustomName : FileName;
|
||||
|
||||
public ImageData()
|
||||
{
|
||||
FileName = string.Empty;
|
||||
_customName = string.Empty;
|
||||
_tags = new List<string>();
|
||||
}
|
||||
|
||||
public ImageData(string fileName, string customName = null, List<string> tags = null)
|
||||
{
|
||||
FileName = fileName;
|
||||
_customName = customName ?? string.Empty;
|
||||
_tags = tags ?? new List<string>();
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -202,7 +202,7 @@ namespace CtrEditor
|
|||
PurgeDeletedObjects();
|
||||
// Asegurarse de que el canvas haya actualizado su layout
|
||||
_canvas.UpdateLayout();
|
||||
|
||||
|
||||
RemoveResizeRectangles();
|
||||
if (_selectedObjects.Any())
|
||||
{
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<Window x:Class="CtrEditor.PopUps.RenameImageWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="Renombrar Imagen" Height="200" Width="400"
|
||||
WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
|
||||
<Grid Margin="20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Text="Archivo original:" FontWeight="Bold" Margin="0,0,0,5"/>
|
||||
<TextBlock Grid.Row="1" x:Name="OriginalNameTextBlock" Margin="0,0,0,10" Foreground="Gray"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Text="Nombre personalizado:" FontWeight="Bold" Margin="0,0,0,5"/>
|
||||
<TextBox Grid.Row="3" x:Name="NewNameTextBox" Margin="0,0,0,15" VerticalAlignment="Top"/>
|
||||
|
||||
<StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button x:Name="OkButton" Content="Aceptar" Width="80" Margin="0,0,10,0" IsDefault="True" Click="OkButton_Click"/>
|
||||
<Button x:Name="CancelButton" Content="Cancelar" Width="80" IsCancel="True" Click="CancelButton_Click"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,34 @@
|
|||
using System.Windows;
|
||||
|
||||
namespace CtrEditor.PopUps
|
||||
{
|
||||
public partial class RenameImageWindow : Window
|
||||
{
|
||||
public string? NewImageName { get; private set; }
|
||||
public bool IsOkClicked { get; private set; }
|
||||
|
||||
public RenameImageWindow(string originalName, string currentCustomName = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
OriginalNameTextBlock.Text = originalName;
|
||||
NewNameTextBox.Text = currentCustomName ?? string.Empty;
|
||||
NewNameTextBox.SelectAll();
|
||||
NewNameTextBox.Focus();
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NewImageName = NewNameTextBox.Text?.Trim();
|
||||
IsOkClicked = true;
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void CancelButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IsOkClicked = false;
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ namespace CtrEditor.Serialization
|
|||
obj.RestaurarDesdeSnapshotGlobal();
|
||||
}
|
||||
|
||||
// Prepara para serialización
|
||||
// Prepara para serializaci<EFBFBD>n
|
||||
obj.SalvarDatosNoSerializables();
|
||||
|
||||
// Separa objetos globales y locales
|
||||
|
@ -64,13 +64,14 @@ namespace CtrEditor.Serialization
|
|||
}
|
||||
}
|
||||
|
||||
// Paso 2: Guardar datos de la página actual
|
||||
// Paso 2: Guardar datos de la p<EFBFBD>gina actual
|
||||
var dataToSerialize = new SimulationData
|
||||
{
|
||||
ObjetosSimulables = objetosSimulables.Count > 0 ? objetosSimulables : null,
|
||||
UnitConverter = PixelToMeter.Instance.calc,
|
||||
PLC_ConnectionData = _mainViewModel.PLCViewModel,
|
||||
DatosLocalesObjetos = datosLocalesObjetos.Count > 0 ? datosLocalesObjetos : null
|
||||
DatosLocalesObjetos = datosLocalesObjetos.Count > 0 ? datosLocalesObjetos : null,
|
||||
ImageDataDictionary = _mainViewModel._imageDataDictionary.Count > 0 ? _mainViewModel._imageDataDictionary : null
|
||||
};
|
||||
|
||||
var path = _datosDeTrabajo.ObtenerPathImagenConExtension(selectedImage, ".json");
|
||||
|
@ -112,11 +113,11 @@ namespace CtrEditor.Serialization
|
|||
// Paso 1: Cargar objetos globales
|
||||
LoadAllPagesState(settings);
|
||||
|
||||
// Paso 2: Cargar datos de la página actual
|
||||
// Paso 2: Cargar datos de la p<EFBFBD>gina actual
|
||||
var simulationData = LoadCurrentPageState(selectedImage, settings);
|
||||
|
||||
// Paso 3: Crear snapshots de los objetos globales
|
||||
// Nota: No filtramos por Enable_Local_Data aquí ya que se establecerá después
|
||||
// Nota: No filtramos por Enable_Local_Data aqu<EFBFBD> ya que se establecer<65> despu<70>s
|
||||
foreach (var obj in _mainViewModel.ObjetosSimulables)
|
||||
{
|
||||
if (obj.Enable_On_All_Pages)
|
||||
|
@ -134,7 +135,7 @@ namespace CtrEditor.Serialization
|
|||
obj.Enable_Local_Data = false;
|
||||
}
|
||||
|
||||
// Luego aplicar los datos locales, esto activará Enable_Local_Data automáticamente
|
||||
// Luego aplicar los datos locales, esto activar<EFBFBD> Enable_Local_Data autom<6F>ticamente
|
||||
foreach (var datosLocales in simulationData.DatosLocalesObjetos)
|
||||
{
|
||||
var objetoGlobal = _mainViewModel.ObjetosSimulables.FirstOrDefault(
|
||||
|
@ -187,6 +188,28 @@ namespace CtrEditor.Serialization
|
|||
_mainViewModel.PLCViewModel = new PLCViewModel();
|
||||
|
||||
PixelToMeter.Instance.calc = simulationData.UnitConverter;
|
||||
|
||||
// Cargar datos de imágenes
|
||||
if (simulationData.ImageDataDictionary != null)
|
||||
{
|
||||
_mainViewModel._imageDataDictionary.Clear();
|
||||
foreach (var imageDataEntry in simulationData.ImageDataDictionary)
|
||||
{
|
||||
_mainViewModel._imageDataDictionary[imageDataEntry.Key] = imageDataEntry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// Compatibilidad con versiones anteriores (ImageCustomNames)
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (simulationData.ImageCustomNames != null)
|
||||
{
|
||||
foreach (var customName in simulationData.ImageCustomNames)
|
||||
{
|
||||
var imageData = _mainViewModel.GetOrCreateImageData(customName.Key);
|
||||
imageData.CustomName = customName.Value;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
}
|
||||
return simulationData;
|
||||
|
|
Loading…
Reference in New Issue