Preparando los UserControl - PArece que la persistencia funciona

This commit is contained in:
Miguel 2024-05-04 11:00:52 +02:00
parent 101a65ad27
commit 73e6f1ef2b
15 changed files with 408 additions and 85 deletions

View File

@ -9,6 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" /> <PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
</ItemGroup> </ItemGroup>

View File

@ -18,6 +18,16 @@ namespace CtrEditor
CargarImagenes(); // Inicializar la carga de imágenes basada en el directorio persistente CargarImagenes(); // Inicializar la carga de imágenes basada en el directorio persistente
} }
public string ObtenerPathImagenConExtension(string key, string extension)
{
if (Imagenes.TryGetValue(key, out string imagePath))
{
string jsonPath = Path.ChangeExtension(imagePath, extension);
return jsonPath;
}
return null;
}
public void CargarImagenes() public void CargarImagenes()
{ {
Imagenes.Clear(); Imagenes.Clear();

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CtrEditor
{
public interface ICtrSimulado
{
string Nombre { get; }
void Update();
// other common methods and properties
}
}

View File

@ -1,5 +1,4 @@
using CtrEditor; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -9,43 +8,47 @@ using System.Threading.Tasks;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Ookii.Dialogs.Wpf; using Ookii.Dialogs.Wpf;
using System.Windows.Input;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using static System.Runtime.InteropServices.JavaScript.JSType; using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Windows.Threading; using System.Windows.Threading;
using CtrEditor.ObjetosSim;
using System.IO;
using System.Windows.Forms;
using System.Text.Json.Serialization;
using System.Text.Json;
using Newtonsoft.Json;
namespace CtrEditor namespace CtrEditor
{ {
public class TickSimulacionEventArgs : EventArgs
{
// Aquí puedes agregar propiedades o campos para pasar información adicional
// en el evento TickSimulacion
}
public class MainViewModel : INotifyPropertyChanged public class MainViewModel : INotifyPropertyChanged
{ {
public DatosDeTrabajo datosDeTrabajo { get; } public DatosDeTrabajo datosDeTrabajo { get; }
public ObservableCollection<string> listaImagenes { get; private set; } // Publicación de las claves del diccionario public ObservableCollection<string> listaImagenes { get; private set; } // Publicación de las claves del diccionario
private ObservableCollection<ICtrSimulado> _funciones; public ObservableCollection<TipoSimulable> ListaOsBase { get; } = new ObservableCollection<TipoSimulable>();
private readonly DispatcherTimer _timerSimulacion; private readonly DispatcherTimer _timerSimulacion;
private string _selectedImage;
public ICommand StartSimulationCommand { get; }
public ICommand StopSimulationCommand { get; }
public ICommand ItemDoubleClickCommand { get; private set; }
// Evento que se dispara cuando se selecciona una nueva imagen // Evento que se dispara cuando se selecciona una nueva imagen
public event EventHandler<string> ImageSelected; public event EventHandler<string> ImageSelected;
public event EventHandler<TickSimulacionEventArgs> TickSimulacion; public event EventHandler<TickSimulacionEventArgs> TickSimulacion;
public event Action<osBase> OnUserControlSelected;
public MainViewModel() public MainViewModel()
{ {
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory); OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
datosDeTrabajo = new DatosDeTrabajo(); datosDeTrabajo = new DatosDeTrabajo();
listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys);
_funciones = new ObservableCollection<ICtrSimulado>(); InitializeTipoSimulableList();
_funciones.Add(new OSBotella());
_funciones.Add(new OSPack()); ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick);
directorioTrabajo = EstadoPersistente.Instance.directorio;
_timerSimulacion = new DispatcherTimer(); _timerSimulacion = new DispatcherTimer();
_timerSimulacion.Interval = TimeSpan.FromMilliseconds(100); // ajusta el intervalo según sea necesario _timerSimulacion.Interval = TimeSpan.FromMilliseconds(100); // ajusta el intervalo según sea necesario
@ -53,10 +56,57 @@ namespace CtrEditor
StartSimulationCommand = new RelayCommand(StartSimulation); StartSimulationCommand = new RelayCommand(StartSimulation);
StopSimulationCommand = new RelayCommand(StopSimulation); StopSimulationCommand = new RelayCommand(StopSimulation);
}
public void LoadInitialData()
{
// Suponiendo que "SelectedImage" es una propiedad que al establecerse dispara "ImageSelected"
directorioTrabajo = EstadoPersistente.Instance.directorio;
}
private TipoSimulable _selectedItem = null;
public TipoSimulable SelectedItem
{
get => _selectedItem;
set
{
if (_selectedItem != value)
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem)); // Notificar que la propiedad ha cambiado
}
}
}
private void ExecuteDoubleClick(object parameter)
{
if (parameter is TipoSimulable tipoSimulable)
{
var instance = Activator.CreateInstance(tipoSimulable.Tipo) as osBase;
if (instance != null)
{
ObjetosSimulables.Add(instance);
OnUserControlSelected?.Invoke(instance);
}
}
}
private void InitializeTipoSimulableList()
{
var baseType = typeof(osBase);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsSubclassOf(baseType) && !type.IsAbstract);
foreach (var type in types)
{
ListaOsBase.Add(new TipoSimulable { Nombre = type.Name, Tipo = type });
}
} }
public ICommand StartSimulationCommand { get; }
public ICommand StopSimulationCommand { get; }
private void StartSimulation() private void StartSimulation()
{ {
@ -90,33 +140,33 @@ namespace CtrEditor
EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado
datosDeTrabajo.CargarImagenes(); datosDeTrabajo.CargarImagenes();
listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys); // Actualizar claves listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys); // Actualizar claves
SelectedImage = null;
if (listaImagenes.FirstOrDefault() != null)
SelectedImage = listaImagenes.FirstOrDefault();
OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad
OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado
} }
} }
} }
public ObservableCollection<ICtrSimulado> CtrSimulado private string _selectedImage = null;
{
get { return _funciones; }
set { _funciones = value; }
}
public string SelectedImage public string SelectedImage
{ {
get => _selectedImage; get => _selectedImage;
set set
{ {
if (_selectedImage != value) if (_selectedImage != value && value != null)
{ {
SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen
_selectedImage = value; _selectedImage = value;
OnPropertyChanged(nameof(SelectedImage)); LoadStateObjetosSimulables();
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen
} }
_selectedImage = value;
OnPropertyChanged(nameof(SelectedImage));
} }
} }
public ICommand OpenWorkDirectoryCommand { get; } public ICommand OpenWorkDirectoryCommand { get; }
private void OpenWorkDirectory() private void OpenWorkDirectory()
@ -128,6 +178,74 @@ namespace CtrEditor
} }
} }
//
// Lista de osBase
//
private ObservableCollection<osBase> objetosSimulables = new ObservableCollection<osBase>();
public ObservableCollection<osBase> ObjetosSimulables
{
get => objetosSimulables;
set
{
if (objetosSimulables != value)
{
objetosSimulables = value;
OnPropertyChanged(nameof(ObjetosSimulables));
}
}
}
public void SaveStateObjetosSimulables()
{
if (_selectedImage != null)
{
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto
};
foreach (var obj in objetosSimulables)
{
obj.VisualRepresentation = null;
}
var serializedData = JsonConvert.SerializeObject(objetosSimulables, settings);
File.WriteAllText(datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"), serializedData);
}
}
public void LoadStateObjetosSimulables()
{
try
{
ObjetosSimulables.Clear();
if (_selectedImage != null)
{
string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json");
if (File.Exists(jsonPath))
{
string jsonString = File.ReadAllText(jsonPath);
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
ObjectCreationHandling = ObjectCreationHandling.Replace,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
objetosSimulables = JsonConvert.DeserializeObject<ObservableCollection<osBase>>(jsonString, settings);
foreach (var obj in objetosSimulables)
{
OnUserControlSelected?.Invoke(obj);
}
}
}
}
catch { /* Consider logging the error or handling it appropriately */ }
}
// Implementación de INotifyPropertyChanged... // Implementación de INotifyPropertyChanged...
@ -137,6 +255,19 @@ namespace CtrEditor
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
}
public class TipoSimulable
{
public string Nombre { get; set; }
public Type Tipo { get; set; }
}
public class TickSimulacionEventArgs : EventArgs
{
// Aquí puedes agregar propiedades o campos para pasar información adicional
// en el evento TickSimulacion
} }
} }

View File

@ -1,6 +1,8 @@
<Window x:Class="CtrEditor.MainWindow" <Window x:Class="CtrEditor.MainWindow"
xmlns:ctreditor="clr-namespace:CtrEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ctreditor="clr-namespace:CtrEditor" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="450" Width="800" Height="450" Width="800"
ResizeMode="CanResize" Title="{Binding directorioTrabajo}"> ResizeMode="CanResize" Title="{Binding directorioTrabajo}">
@ -35,7 +37,13 @@
<RowDefinition Height="1*"/> <RowDefinition Height="1*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding listaImagenes}" SelectedItem="{Binding SelectedImage}" /> <ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding listaImagenes}" SelectedItem="{Binding SelectedImage}" />
<ListBox x:Name="ListaFunciones" Grid.Row="1" Margin="5" ItemsSource="{Binding CtrSimulado}" DisplayMemberPath="Nombre"/> <ListBox x:Name="ListaFunciones" Grid.Row="1" Margin="5" ItemsSource="{Binding ListaOsBase}" DisplayMemberPath="Nombre" SelectedItem="{Binding SelectedItem}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding ItemDoubleClickCommand}" CommandParameter="{Binding SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
</Grid> </Grid>
<!-- GridSplitter --> <!-- GridSplitter -->
<GridSplitter Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right" Width="5" Background="LightGray" /> <GridSplitter Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right" Width="5" Background="LightGray" />
@ -43,7 +51,7 @@
<!-- Segunda Columna --> <!-- Segunda Columna -->
<Grid Grid.Column="1"> <Grid Grid.Column="1">
<ScrollViewer x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" PanningMode="Both"> <ScrollViewer x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" PanningMode="Both">
<Canvas x:Name="ImagenEnTrabajoCanvas" Margin="200"> <Canvas x:Name="ImagenEnTrabajoCanvas" Margin="20">
<!-- El Margin puede ser ajustado según el espacio adicional que quieras proporcionar --> <!-- El Margin puede ser ajustado según el espacio adicional que quieras proporcionar -->
<Canvas.LayoutTransform> <Canvas.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/> <ScaleTransform ScaleX="1" ScaleY="1"/>

View File

@ -8,6 +8,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using CtrEditor.ObjetosSim;
namespace CtrEditor namespace CtrEditor
{ {
@ -36,8 +37,56 @@ namespace CtrEditor
{ {
viewModel.ImageSelected += ViewModel_ImageSelected; viewModel.ImageSelected += ViewModel_ImageSelected;
viewModel.TickSimulacion += MainViewModel_TickSimulacion; viewModel.TickSimulacion += MainViewModel_TickSimulacion;
viewModel.OnUserControlSelected += AgregarUserControl;
viewModel?.LoadInitialData(); // Carga la primera imagen por defecto una vez cargada la ventana principal
} }
} }
private void AgregarUserControl(osBase NuevoOS)
{
if (NuevoOS != null)
{
if (NuevoOS.VisualRepresentation is null)
{
UserControl userControl = UserControlFactory.GetControlForType(NuevoOS.GetType());
NuevoOS.VisualRepresentation = userControl;
if (!NuevoOS.Inicializado) // Aun no fue inicializado
{
// Obtiene el área visible del ScrollViewer
var visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth;
var visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight;
// Obtiene la posición actual del desplazamiento
var offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset;
var offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset;
// Calcula el centro visible del Canvas
double centerX = offsetX + visibleWidth / 2;
double centerY = offsetY + visibleHeight / 2;
// Ajusta la posición del UserControl para que esté centrado en el área visible
double left = centerX - (userControl.ActualWidth / 2);
double top = centerY - (userControl.ActualHeight / 2);
// Establece la posición del UserControl
Canvas.SetLeft(userControl, left);
Canvas.SetTop(userControl, top);
NuevoOS.x = left;
NuevoOS.y = top;
NuevoOS.Inicializado = true;
}
// Añade el UserControl al Canvas
ImagenEnTrabajoCanvas.Children.Add(userControl);
}
}
}
private void ViewModel_ImageSelected(object sender, string imagePath) private void ViewModel_ImageSelected(object sender, string imagePath)
{ {
LoadImageToCanvas(imagePath); LoadImageToCanvas(imagePath);
@ -59,7 +108,7 @@ namespace CtrEditor
// Elimina solo los ROIs, no la imagen de fondo // Elimina solo los ROIs, no la imagen de fondo
for (int i = ImagenEnTrabajoCanvas.Children.Count - 1; i >= 0; i--) for (int i = ImagenEnTrabajoCanvas.Children.Count - 1; i >= 0; i--)
{ {
if (ImagenEnTrabajoCanvas.Children[i] is Rectangle) if (ImagenEnTrabajoCanvas.Children[i] is not Image)
{ {
ImagenEnTrabajoCanvas.Children.RemoveAt(i); ImagenEnTrabajoCanvas.Children.RemoveAt(i);
} }
@ -146,7 +195,7 @@ namespace CtrEditor
// en el ImagenEnTrabajoCanvas // en el ImagenEnTrabajoCanvas
foreach (var child in ImagenEnTrabajoCanvas.Children) foreach (var child in ImagenEnTrabajoCanvas.Children)
{ {
if (child is ICtrSimulado uc) if (child is osBase uc)
{ {
// llama al método Update de cada UserControl // llama al método Update de cada UserControl
uc.Update(); uc.Update();

View File

@ -1,6 +0,0 @@
<UserControl x:Class="CtrEditor.OSPack"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="150">
<Border Background="Gray" CornerRadius="2" Height="10" Width="10"/>
</UserControl>

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace CtrEditor.ObjetosSim
{
public static class UserControlFactory
{
public static UserControl GetControlForType(Type tipoObjeto)
{
if (tipoObjeto == typeof(osBotella))
return new ucBotella();
if (tipoObjeto == typeof(osTransporteTTop))
return new ucTransporteTTop();
// Puedes añadir más condiciones para otros tipos
return null;
}
}
}

44
ObjetosSim/osBase.cs Normal file
View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace CtrEditor.ObjetosSim
{
public interface IosBase
{
string Nombre { get; }
void Update();
}
public abstract class osBase : IosBase
{
private UserControl? _visualRepresentation = null;
[JsonIgnore]
public UserControl? VisualRepresentation
{
get => _visualRepresentation;
set => _visualRepresentation = value;
}
// Método para inicializar la representación visual, si es necesario
//public void InitializeVisualRepresentation()
//{
// // Suponiendo que existe un método estático para obtener el UserControl adecuado
// _visualRepresentation = UserControlFactory.GetControlForType(this.GetType());
//}
public string Nombre => "Base";
public abstract void Update();
public bool Inicializado = false;
public double x { get; set; }
public double y { get; set; }
}
}

View File

@ -1,6 +1,5 @@
<UserControl x:Class="CtrEditor.OSBotella" <UserControl x:Class="CtrEditor.ObjetosSim.ucBotella"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
Width="100" Height="300">
<Border Background="Brown" CornerRadius="10" Height="10" Width="10"/> <Border Background="Brown" CornerRadius="10" Height="10" Width="10"/>
</UserControl> </UserControl>

View File

@ -13,22 +13,30 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace CtrEditor namespace CtrEditor.ObjetosSim
{ {
/// <summary> /// <summary>
/// Interaction logic for ObjetoSimuladoPack.xaml /// Interaction logic for ucBotella.xaml
/// </summary> /// </summary>
public partial class OSPack : UserControl, ICtrSimulado ///
public class osBotella : osBase
{ {
public OSPack() public double diametro { get; set; }
{ // Otros datos y métodos relevantes para la simulación
InitializeComponent();
} public new string Nombre => "Botella";
public string Nombre => "Packs"; public override void Update()
public void Update()
{ {
// implementation of Update method // implementation of Update method
} }
} }
public partial class ucBotella : UserControl
{
public ucBotella()
{
InitializeComponent();
}
}
} }

View File

@ -0,0 +1,9 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucTransporteTTop"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CtrEditor"
mc:Ignorable="d" >
<Rectangle HorizontalAlignment="Left" Height="10" Margin="0,0,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
</UserControl>

View File

@ -13,22 +13,30 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace CtrEditor namespace CtrEditor.ObjetosSim
{ {
/// <summary> /// <summary>
/// Interaction logic for ObjetoSimuladoBotella.xaml /// Interaction logic for ucTransporteTTop.xaml
/// </summary> /// </summary>
public partial class OSBotella : UserControl, ICtrSimulado ///
public class osTransporteTTop : osBase
{ {
public OSBotella() public double diametro { get; set; }
{ // Otros datos y métodos relevantes para la simulación
InitializeComponent();
} public new string Nombre => "Transporte TTOP";
public string Nombre => "Botellas"; public override void Update()
public void Update()
{ {
// implementation of Update method // implementation of Update method
} }
} }
public partial class ucTransporteTTop : UserControl
{
public ucTransporteTTop()
{
InitializeComponent();
}
}
} }

View File

@ -39,4 +39,37 @@ namespace CtrEditor
CommandManager.InvalidateRequerySuggested(); CommandManager.InvalidateRequerySuggested();
} }
} }
public class ParameterizedRelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public ParameterizedRelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
}
} }

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json;
using System; using System;
using System.IO; using System.IO;
using System.Text.Json;
namespace CtrEditor namespace CtrEditor
{ {
@ -28,9 +28,14 @@ namespace CtrEditor
} }
// Constructor privado para evitar la instanciación externa // Constructor privado para evitar la instanciación externa
private EstadoPersistente() public EstadoPersistente()
{
}
private EstadoPersistente Inizializar()
{ {
_strDirectorioTrabajo = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); _strDirectorioTrabajo = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return this;
} }
// Propiedad pública estática para acceder a la instancia // Propiedad pública estática para acceder a la instancia
@ -47,21 +52,34 @@ namespace CtrEditor
} }
// Método para guardar el estado en un archivo JSON // Método para guardar el estado en un archivo JSON
public void GuardarEstado() public void GuardarEstado()
{ {
string json = JsonConvert.SerializeObject(this); var options = new JsonSerializerOptions
{
WriteIndented = true // para una salida JSON formateada legiblemente
};
string json = JsonSerializer.Serialize(this, options);
File.WriteAllText(_filePath, json); File.WriteAllText(_filePath, json);
} }
// Método estático para cargar el estado desde un archivo JSON // Método estático para cargar el estado desde un archivo JSON
private static EstadoPersistente CargarEstado() private static EstadoPersistente CargarEstado()
{ {
if (File.Exists(_filePath)) try
{ {
string json = File.ReadAllText(_filePath); if (File.Exists(_filePath))
return JsonConvert.DeserializeObject<EstadoPersistente>(json); {
string json = File.ReadAllText(_filePath);
return JsonSerializer.Deserialize<EstadoPersistente>(json);
}
return new EstadoPersistente().Inizializar(); // Devuelve una nueva instancia si no existe el archivo
} catch
{
return new EstadoPersistente().Inizializar(); // Devuelve una nueva instancia si no existe el archivo
} }
return new EstadoPersistente(); // Devuelve una nueva instancia si no existe el archivo
} }
} }