Mejorado de la exportacion a Excel

This commit is contained in:
Miguel 2024-06-11 12:30:27 +02:00
parent 922a46d616
commit 759ee627e2
8 changed files with 277 additions and 160 deletions

View File

@ -386,6 +386,7 @@ namespace CtrEditor
assignImagesViewModel.Initialize(this, assignImagesWindow); assignImagesViewModel.Initialize(this, assignImagesWindow);
assignImagesWindow.DataContext = assignImagesViewModel; assignImagesWindow.DataContext = assignImagesViewModel;
assignImagesWindow.ShowDialog(); assignImagesWindow.ShowDialog();
if (assignImagesWindow.DataContext is AssignImagesViewModel dialog && dialog.CloseOK)
SaveStateObjetosSimulables(); SaveStateObjetosSimulables();
} }
@ -398,7 +399,10 @@ namespace CtrEditor
private async void MultiPageExtractTagsCommand() private async void MultiPageExtractTagsCommand()
{ {
var ImagenesSeleccionadas = new ObservableCollection<string>(); var ImagenesSeleccionadas = new ObservableCollection<string>
{
SelectedImage
};
StopSimulation(); StopSimulation();
@ -408,6 +412,7 @@ namespace CtrEditor
selectPagesWindow.DataContext = selectPagesViewModel; selectPagesWindow.DataContext = selectPagesViewModel;
selectPagesWindow.ShowDialog(); selectPagesWindow.ShowDialog();
if (selectPagesWindow.DataContext is SelectPagesViewModel dialog && dialog.CloseOK)
foreach (var page in ImagenesSeleccionadas) foreach (var page in ImagenesSeleccionadas)
{ {
SelectedImage = page; SelectedImage = page;
@ -418,7 +423,10 @@ namespace CtrEditor
private async void MultiPageAnalizeCommand() private async void MultiPageAnalizeCommand()
{ {
var ImagenesSeleccionadas = new ObservableCollection<string>(); var ImagenesSeleccionadas = new ObservableCollection<string>
{
SelectedImage
};
StopSimulation(); StopSimulation();
@ -446,6 +454,7 @@ namespace CtrEditor
{ {
foreach (var obj in ObjetosSimulables) foreach (var obj in ObjetosSimulables)
if (obj is osBuscarCoincidencias objBC) if (obj is osBuscarCoincidencias objBC)
if (objBC.Show_On_This_Page)
objBC.BuscarCoincidencias(); objBC.BuscarCoincidencias();
} }
@ -462,7 +471,6 @@ namespace CtrEditor
try try
{ {
int colFix = 0;
// Crea o abre un libro de Excel. // Crea o abre un libro de Excel.
XLWorkbook workbook = File.Exists(filePath) ? new XLWorkbook(filePath) : new XLWorkbook(); XLWorkbook workbook = File.Exists(filePath) ? new XLWorkbook(filePath) : new XLWorkbook();
var sheetName = "TagsExtracted"; var sheetName = "TagsExtracted";
@ -470,52 +478,95 @@ namespace CtrEditor
var worksheet = workbook.Worksheets.Contains(sheetName) ? workbook.Worksheet(sheetName) : workbook.Worksheets.Add(sheetName); var worksheet = workbook.Worksheets.Contains(sheetName) ? workbook.Worksheet(sheetName) : workbook.Worksheets.Add(sheetName);
var lastRowUsed = worksheet.LastRowUsed(); var lastRowUsed = worksheet.LastRowUsed();
// Determina la fila en la que se empezarán a escribir los datos. // Determina la fila en la que se empezarán a escribir los datos.
int row = lastRowUsed == null ? 2 : lastRowUsed.RowNumber() + 1; int rowOffset = lastRowUsed == null ? 2 : lastRowUsed.RowNumber() + 1;
// Determina la columna fija más alta. // Determina la columna fija más alta.
foreach (var obj in ObjetosSimulables) List<int> columnasOcupadas = new List<int>();
int actualMaxCol = 0;
int col = 0;
// Filtrar los objetos de tipo osExtraccionTag y crear una nueva lista
var osBuscarCoincidencias_List = ObjetosSimulables.OfType<osBuscarCoincidencias>().ToList();
var osExtraccionTagBaseGrouped_List = ObjetosSimulables
.OfType<osExtraccionTag>()
.Where(tag => !tag.Cloned && tag.Id_Search_Templates != null && tag.Id_Search_Templates != "")
.ToList();
var osExtraccionTagBaseFix_List = ObjetosSimulables
.OfType<osExtraccionTag>()
.Where(tag => !tag.Cloned && (tag.Id_Search_Templates == null || tag.Id_Search_Templates == ""))
.ToList();
var osExtraccionTagCloned_List = ObjetosSimulables
.OfType<osExtraccionTag>()
.Where(tag => tag.Cloned)
.ToList();
// Columnas Fijas para los Tags no agrupados que no son clonados
foreach (var objExtraccionTag in osExtraccionTagBaseFix_List)
if ((string.IsNullOrEmpty(objExtraccionTag.Id_Search_Templates)) && !objExtraccionTag.Cloned)
{ {
if (obj is osExtraccionTag objExtraccionTag && (objExtraccionTag.Id_Search_Templates == null || objExtraccionTag.Id_Search_Templates == "") && !objExtraccionTag.Cloned) col = objExtraccionTag.Collumn_number;
if (col == 0 || columnasOcupadas.Contains(col))
col = ++actualMaxCol;
else
actualMaxCol = Math.Max(actualMaxCol, col);
columnasOcupadas.Add(col);
objExtraccionTag.Collumn_number = col;
}
// Tags Agrupados no Clonados
foreach (var objBC in osBuscarCoincidencias_List)
foreach (var objExtraccionTag in osExtraccionTagBaseGrouped_List)
if (objExtraccionTag.Id_Search_Templates == objBC.Nombre && !objExtraccionTag.Cloned)
{ {
colFix = Math.Max(colFix, objExtraccionTag.Collumn_number); col = objExtraccionTag.Collumn_number;
if (col == 0 || columnasOcupadas.Contains(col))
col = ++actualMaxCol;
else
actualMaxCol = Math.Max(actualMaxCol, col);
columnasOcupadas.Add(col);
objExtraccionTag.Collumn_number = col;
}
int RowToRender = 0;
// Cloned Tag - Asignar las mismas columnas
foreach (var oFrom in osExtraccionTagBaseGrouped_List)
foreach (var oCloned in osExtraccionTagCloned_List)
{
if (oCloned.Cloned_from == oFrom.Id)
oCloned.Collumn_number = oFrom.Collumn_number;
RowToRender = Math.Max(RowToRender, oCloned.Copy_Number);
}
// Render Rows
for (int row = 0; row < RowToRender; row++)
{
// Render Fix tags
foreach (var TagFixs in osExtraccionTagBaseFix_List)
{
col = TagFixs.Collumn_number;
if (worksheet.Cell(1, col).IsEmpty())
worksheet.Cell(1, col).Value = TagFixs.Collumn_name;
TagFixs.CaptureImageAreaAndDoOCR();
worksheet.Cell(row + rowOffset, col).Value = TagFixs.Tag_extract;
}
// Render Cloned tags
foreach (var TagCloned in osExtraccionTagCloned_List)
{
if (TagCloned.Copy_Number == row) // Estamos en la fila correcta
{
col = TagCloned.Collumn_number;
if (worksheet.Cell(1, col).IsEmpty())
worksheet.Cell(1, col).Value = TagCloned.Collumn_name;
TagCloned.CaptureImageAreaAndDoOCR();
worksheet.Cell(row + rowOffset, col).Value = TagCloned.Tag_extract;
}
} }
} }
int colNextGroup = 0;
// Itera sobre los objetos simulables para extraer y guardar las etiquetas.
foreach (var obj in ObjetosSimulables)
{
if (obj is osBuscarCoincidencias objBC)
{
int maxColGroup = 0;
foreach (var objchild in ObjetosSimulables)
{
if (objchild is osExtraccionTag objExtraccionTag && objExtraccionTag.Id_Search_Templates == objBC.Nombre && objExtraccionTag.Cloned)
{
foreach (var objfix in ObjetosSimulables)
{
if (objfix is osExtraccionTag objExtraccionTagNoGroup && (objExtraccionTagNoGroup.Id_Search_Templates == null || objExtraccionTagNoGroup.Id_Search_Templates == "") && !objExtraccionTagNoGroup.Cloned)
{
if (worksheet.Cell(1, objExtraccionTagNoGroup.Collumn_number).IsEmpty())
worksheet.Cell(1, objExtraccionTagNoGroup.Collumn_number).Value = objExtraccionTagNoGroup.Collumn_name;
objExtraccionTagNoGroup.CaptureImageAreaAndDoOCR();
worksheet.Cell(row, objExtraccionTagNoGroup.Collumn_number).Value = objExtraccionTagNoGroup.Tag_extract;
}
}
objExtraccionTag.CaptureImageAreaAndDoOCR();
worksheet.Cell(row, objExtraccionTag.Collumn_number + colFix + colNextGroup).Value = objExtraccionTag.Tag_extract;
if (worksheet.Cell(1, objExtraccionTag.Collumn_number + colFix + colNextGroup).IsEmpty())
worksheet.Cell(1, objExtraccionTag.Collumn_number + colFix + colNextGroup).Value = objExtraccionTag.Collumn_name;
maxColGroup = Math.Max(maxColGroup, objExtraccionTag.Collumn_number);
if (objExtraccionTag.New_Row) row++;
}
}
colNextGroup += maxColGroup;
}
}
// Formatear los títulos en la fila 1 // Formatear los títulos en la fila 1
var titleRow = worksheet.Row(1); var titleRow = worksheet.Row(1);

View File

@ -145,7 +145,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
[ObservableProperty] [ObservableProperty]
[property: Category("Tag Extraction:")] [property: Category("Tag Extraction:")]
[property: ReadOnly(true)] [property: ReadOnly(true)]
float coincidencias; int coincidencias;
public osBuscarCoincidencias() public osBuscarCoincidencias()
{ {
@ -278,7 +278,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
search_rectangles = new List<Rect>(); search_rectangles = new List<Rect>();
// Añadir el rectángulo usado por croppedBitmap a search_rectangles // Añadir el rectángulo usado por croppedBitmap a search_rectangles
search_rectangles.Add(new Rect(x / scaleFactorX, y / scaleFactorY, width / scaleFactorX, height / scaleFactorY)); //search_rectangles.Add(new Rect(x / scaleFactorX, y / scaleFactorY, width / scaleFactorX, height / scaleFactorY));
// Obtener los puntos que superan el umbral // Obtener los puntos que superan el umbral
float[] resultArray = result.GetData(false) as float[]; float[] resultArray = result.GetData(false) as float[];
@ -349,9 +349,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
var objetosSimulables2Copy = new List<osBase>(_mainViewModel.ObjetosSimulables); var objetosSimulables2Copy = new List<osBase>(_mainViewModel.ObjetosSimulables);
// Saltar el primer rectángulo en el foreach // Saltar el primer rectángulo en el foreach
int Row = 0;
foreach (var rectangle in search_rectangles) //.Skip(1))
foreach (var rectangle in search_rectangles.Skip(1))
{ {
float offsetX = PixelsToMeters((float)rectangle.X) - Left; float offsetX = PixelsToMeters((float)rectangle.X) - Left;
float offsetY = PixelsToMeters((float)rectangle.Y) - Top; float offsetY = PixelsToMeters((float)rectangle.Y) - Top;
@ -368,6 +367,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
if (newObj != null) if (newObj != null)
{ {
newObj.Cloned = true; newObj.Cloned = true;
newObj.Cloned_from = objExtraccionTag.Id;
newObj.Copy_Number = Row;
newObj.Enable_On_All_Pages = false; newObj.Enable_On_All_Pages = false;
if (newObj.Extraer) if (newObj.Extraer)
objExtraccionTag.CaptureImageAreaAndDoOCR(); objExtraccionTag.CaptureImageAreaAndDoOCR();
@ -375,6 +376,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
} }
} }
} }
Row++;
if (newObj != null) if (newObj != null)
newObj.New_Row = true; newObj.New_Row = true;

View File

@ -13,15 +13,23 @@
</UserControl.DataContext> </UserControl.DataContext>
<Canvas> <Canvas>
<Rectangle x:Name="Area" <Rectangle x:Name="Area" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Opacity="{Binding Opacity_oculto}" Fill="Green" Opacity="{Binding Opacity_oculto}" Fill="Green" Stroke="Black">
Stroke="Black"
>
<Rectangle.RenderTransform>
<RotateTransform Angle="{Binding Angulo}"/>
</Rectangle.RenderTransform>
</Rectangle> </Rectangle>
<Viewbox Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}">
<Label Content="{Binding Angulo}" VerticalAlignment="Top" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,0.5" Opacity="0.1">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="{Binding Angulo}" />
<TranslateTransform />
</TransformGroup>
</Label.RenderTransform>
</Label>
</Viewbox>
</Canvas> </Canvas>
</UserControl> </UserControl>

View File

@ -38,6 +38,12 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
[property: Category("Tag Extraction:")] [property: Category("Tag Extraction:")]
bool cloned; bool cloned;
[ObservableProperty]
[property: Description("Autocreated and cloned with Search Templates")]
[property: Category("Tag Extraction:")]
[property: Hidden]
UniqueId cloned_from;
[ObservableProperty] [ObservableProperty]
bool new_Row; bool new_Row;
@ -76,7 +82,18 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
ResetTimer(); ResetTimer();
} }
[ObservableProperty]
[property: Category("Layout:")]
public float angulo;
partial void OnAnguloChanged(float value)
{
ResetTimer();
}
public override void OnTimerAfterMovement() { public override void OnTimerAfterMovement() {
Angulo = (float)Math.Round(Angulo / 90) * 90;
if (Extraer) if (Extraer)
CaptureImageAreaAndDoOCR(); CaptureImageAreaAndDoOCR();
} }
@ -110,10 +127,6 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
} }
} }
[ObservableProperty]
[property: Category("Layout:")]
public float angulo;
[ObservableProperty] [ObservableProperty]
[property: Category("Tag Extraction:")] [property: Category("Tag Extraction:")]
string tag_extract; string tag_extract;
@ -131,6 +144,16 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
[property: Category("Export:")] [property: Category("Export:")]
int collumn_number; int collumn_number;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: ReadOnly(true)]
int copy_Number;
[ObservableProperty]
[property: Category("Tag Extraction:")]
bool show_Debug_Window;
[ObservableProperty] [ObservableProperty]
float opacity_oculto; float opacity_oculto;
@ -144,7 +167,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
public void CaptureImageAreaAndDoOCR() public void CaptureImageAreaAndDoOCR()
{ {
Tag_extract = CaptureImageAreaAndDoOCR(Left, Top, Ancho, Alto); Tag_extract = CaptureImageAreaAndDoOCR(Left, Top, Ancho, Alto, Angulo, Show_Debug_Window);
} }
public int ExportToExcel(IXLWorksheet worksheet, int row, int colBase) public int ExportToExcel(IXLWorksheet worksheet, int row, int colBase)

View File

@ -179,64 +179,82 @@ namespace CtrEditor.ObjetosSim
} }
public string CaptureImageAreaAndDoOCR(float Left, float Top, float Ancho, float Alto) public string CaptureImageAreaAndDoOCR(float Left, float Top, float Ancho, float Alto, float Angulo = 0, bool ShowPreview = false)
{ {
if (_mainViewModel?.MainCanvas.Children[0] is Image imagenDeFondo) if (_mainViewModel?.MainCanvas.Children[0] is Image imagenDeFondo)
{ {
// Asegurarse de que la imagen origen está disponible
if (imagenDeFondo.Source is BitmapSource bitmapSource) if (imagenDeFondo.Source is BitmapSource bitmapSource)
{ {
// Obtener los DPI de la imagen original
float originalDpiX = (float)bitmapSource.DpiX; float originalDpiX = (float)bitmapSource.DpiX;
float originalDpiY = (float)bitmapSource.DpiY; float originalDpiY = (float)bitmapSource.DpiY;
// Estándar DPI en el que el Canvas renderiza la imagen float canvasDpiX = 96;
float canvasDpiX = 96; // WPF usually renders at 96 DPI
float canvasDpiY = 96; float canvasDpiY = 96;
// Calcular el ratio de escala entre el Canvas y la imagen original
float scaleFactorX = originalDpiX / canvasDpiX; float scaleFactorX = originalDpiX / canvasDpiX;
float scaleFactorY = originalDpiY / canvasDpiY; float scaleFactorY = originalDpiY / canvasDpiY;
// Ajustar las coordenadas de recorte en función del ratio de escala
int x = (int)MeterToPixels(Left * scaleFactorX); int x = (int)MeterToPixels(Left * scaleFactorX);
int y = (int)MeterToPixels(Top * scaleFactorY); int y = (int)MeterToPixels(Top * scaleFactorY);
int width = (int)MeterToPixels(Ancho * scaleFactorX); int width = (int)MeterToPixels(Ancho * scaleFactorX);
int height = (int)MeterToPixels(Alto * scaleFactorY); int height = (int)MeterToPixels(Alto * scaleFactorY);
// Validar y ajustar el tamaño del recorte para que se mantenga dentro de los límites de la imagen
if (x < 0) x = 0; if (x < 0) x = 0;
if (y < 0) y = 0; if (y < 0) y = 0;
if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x; if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y; if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y;
// Recortar el área deseada utilizando las coordenadas ajustadas
CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height)); CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height));
// Codificar el bitmap recortado a un MemoryStream TransformedBitmap transformedBitmap = new TransformedBitmap();
transformedBitmap.BeginInit();
transformedBitmap.Source = croppedBitmap;
if (Angulo != 0)
{
RotateTransform rotateTransform = new RotateTransform(-Angulo);
transformedBitmap.Transform = rotateTransform;
}
transformedBitmap.EndInit();
PngBitmapEncoder encoder = new PngBitmapEncoder(); PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(croppedBitmap)); encoder.Frames.Add(BitmapFrame.Create(transformedBitmap));
using (MemoryStream memoryStream = new MemoryStream()) using (MemoryStream memoryStream = new MemoryStream())
{ {
encoder.Save(memoryStream); encoder.Save(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.Seek(0, SeekOrigin.Begin);
//ShowPreviewWindow(memoryStream); if (ShowPreview) ShowPreviewWindow(memoryStream);
// Cargar la imagen en Tesseract desde el MemoryStream using (var bmp = new System.Drawing.Bitmap(memoryStream))
using (var img = Pix.LoadFromMemory(memoryStream.ToArray())) {
int targetDpi = 400;
var resizedBmp = new System.Drawing.Bitmap(bmp, new System.Drawing.Size(bmp.Width * targetDpi / (int)originalDpiX, bmp.Height * targetDpi / (int)originalDpiY));
using (var msResized = new MemoryStream())
{
resizedBmp.Save(msResized, System.Drawing.Imaging.ImageFormat.Png);
msResized.Seek(0, SeekOrigin.Begin);
using (var img = Pix.LoadFromMemory(msResized.ToArray()))
using (var engine = new TesseractEngine(@"./Tesseract", "eng", EngineMode.Default)) using (var engine = new TesseractEngine(@"./Tesseract", "eng", EngineMode.Default))
{ {
// Configuraciones para mejorar el OCR de una sola letra
engine.SetVariable("tessedit_char_whitelist", " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."); // Lista blanca de caracteres
var result = engine.Process(img); var result = engine.Process(img);
return result.GetText(); return result.GetText();
} }
} }
} }
} }
}
}
return ""; return "";
} }
// All Pages Objects // All Pages Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))] [NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty] [ObservableProperty]
@ -817,6 +835,7 @@ namespace CtrEditor.ObjetosSim
public class UniqueId public class UniqueId
{ {
public int Value { get; set; } public int Value { get; set; }
public UniqueId ObtenerNuevaID() public UniqueId ObtenerNuevaID()
{ {
Value = EstadoPersistente.Instance.newid; Value = EstadoPersistente.Instance.newid;
@ -824,13 +843,64 @@ namespace CtrEditor.ObjetosSim
Value++; Value++;
return this; return this;
} }
public void NoId() public void NoId()
{ {
// No ID == NULL // No ID == NULL
Value = 0; Value = 0;
} }
// Sobrecarga del operador ++
public static UniqueId operator ++(UniqueId id)
{
if (id == null)
{
id = new UniqueId();
} }
id.Value = EstadoPersistente.Instance.newid;
if (id.Value == 0)
id.Value++;
return id;
}
// Sobrecarga del operador ==
public static bool operator ==(UniqueId id1, UniqueId id2)
{
if (ReferenceEquals(id1, null) || ReferenceEquals(id2, null))
return false;
return id1.Value == id2.Value;
}
// Sobrecarga del operador !=
public static bool operator !=(UniqueId id1, UniqueId id2)
{
if (ReferenceEquals(id1, null) || ReferenceEquals(id2, null))
return true;
return id1.Value != id2.Value;
}
// Sobrescribir Equals y GetHashCode también es una buena práctica
public override bool Equals(object obj)
{
if (obj is UniqueId id)
{
return Value == id.Value;
}
return false;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
public class osBaseItemsSource<T> : IItemsSource public class osBaseItemsSource<T> : IItemsSource
{ {
public ItemCollection GetValues() public ItemCollection GetValues()

View File

@ -58,13 +58,9 @@
</ToolBarTray> </ToolBarTray>
<!-- Lista de Objetos --> <!-- Lista de Objetos -->
<ListBox x:Name="ListaObjetosSim" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding ObjetosSimulables}" <xctk:CheckListBox Grid.Row="1" Grid.Column="0" ItemsSource="{Binding ObjetosSimulables}" DisplayMemberPath="Nombre"
DisplayMemberPath="Nombre" SelectionMode="Multiple"> SelectedItemsOverride="{Binding SelectedObjetosSimulables, Mode=TwoWay}" />
<i:Interaction.Behaviors>
<local:SelectedItemsBehavior SelectedItems="{Binding SelectedObjetosSimulables, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</ListBox>
<DataGrid />
<!-- Lista de Imágenes con CheckListBox --> <!-- Lista de Imágenes con CheckListBox -->
<xctk:CheckListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding ListaImagenes}" DisplayMemberPath="." <xctk:CheckListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding ListaImagenes}" DisplayMemberPath="."
SelectedItemsOverride="{Binding SelectedImagenes, Mode=TwoWay}" /> SelectedItemsOverride="{Binding SelectedImagenes, Mode=TwoWay}" />

View File

@ -1,13 +1,9 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using CtrEditor.ObjetosSim; using CtrEditor.ObjetosSim;
using CtrEditor;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Collections;
using CtrEditor.ObjetosSim.Extraccion_Datos; using CtrEditor.ObjetosSim.Extraccion_Datos;
using Microsoft.Xaml.Behaviors;
namespace CtrEditor.PopUps namespace CtrEditor.PopUps
@ -21,13 +17,14 @@ namespace CtrEditor.PopUps
{ {
InitializeComponent(); InitializeComponent();
} }
} }
public partial class AssignImagesViewModel : ObservableObject public partial class AssignImagesViewModel : ObservableObject
{ {
private MainViewModel _mainViewModel; private MainViewModel _mainViewModel;
private Window _window; private Window _window;
private bool _closeOK;
[ObservableProperty] [ObservableProperty]
private ObservableCollection<osBase> objetosSimulables; private ObservableCollection<osBase> objetosSimulables;
@ -40,7 +37,11 @@ namespace CtrEditor.PopUps
[ObservableProperty] [ObservableProperty]
private ObservableCollection<string> selectedImagenes; private ObservableCollection<string> selectedImagenes;
public AssignImagesViewModel() { } public AssignImagesViewModel()
{
SelectedObjetosSimulables = new ObservableCollection<osBase>();
SelectedObjetosSimulables.CollectionChanged += SelectedObjetosSimulables_CollectionChanged;
}
public void Initialize(MainViewModel mainViewModel, Window window) public void Initialize(MainViewModel mainViewModel, Window window)
{ {
@ -50,8 +51,26 @@ namespace CtrEditor.PopUps
o => o.Enable_On_All_Pages && ((o is osExtraccionTag ex && !ex.Cloned) || (o is osBuscarCoincidencias)))); o => o.Enable_On_All_Pages && ((o is osExtraccionTag ex && !ex.Cloned) || (o is osBuscarCoincidencias))));
ListaImagenes = _mainViewModel.ListaImagenes; ListaImagenes = _mainViewModel.ListaImagenes;
SelectedObjetosSimulables = new ObservableCollection<osBase>(); }
SelectedImagenes = new ObservableCollection<string>();
private void SelectedObjetosSimulables_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
UpdateSelectedImages();
}
private void UpdateSelectedImages()
{
var selectedImages = new HashSet<string>();
foreach (var objeto in SelectedObjetosSimulables)
{
foreach (var image in objeto.ShowOnThisPagesList)
{
selectedImages.Add(image);
}
}
SelectedImagenes = new ObservableCollection<string>(selectedImages);
} }
[RelayCommand] [RelayCommand]
@ -62,7 +81,7 @@ namespace CtrEditor.PopUps
objeto.ShowOnThisPagesList = new List<string>(SelectedImagenes); objeto.ShowOnThisPagesList = new List<string>(SelectedImagenes);
objeto.Show_On_This_Page = objeto.Show_On_This_Page; objeto.Show_On_This_Page = objeto.Show_On_This_Page;
} }
_closeOK = true;
_window.Close(); _window.Close();
} }
@ -97,67 +116,11 @@ namespace CtrEditor.PopUps
{ {
SelectedImagenes.Clear(); SelectedImagenes.Clear();
} }
public bool CloseOK => _closeOK;
} }
public class SelectedItemsBehavior : Behavior<ListBox>
{
public IList SelectedItems
{
get { return (IList)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
}
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems", typeof(IList), typeof(SelectedItemsBehavior), new PropertyMetadata(null, OnSelectedItemsChanged));
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += OnSelectionChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.SelectionChanged -= OnSelectionChanged;
}
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var behavior = d as SelectedItemsBehavior;
behavior?.UpdateSelectedItems();
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (SelectedItems != null)
{
foreach (var item in e.RemovedItems)
{
SelectedItems.Remove(item);
}
foreach (var item in e.AddedItems)
{
SelectedItems.Add(item);
}
}
}
private void UpdateSelectedItems()
{
if (SelectedItems != null)
{
AssociatedObject.SelectionChanged -= OnSelectionChanged;
AssociatedObject.SelectedItems.Clear();
foreach (var item in SelectedItems)
{
AssociatedObject.SelectedItems.Add(item);
}
AssociatedObject.SelectionChanged += OnSelectionChanged;
}
}
}
} }

View File

@ -39,6 +39,8 @@ public partial class SelectPagesViewModel : ObservableObject
private Window _window; private Window _window;
private ObservableCollection<string> _imagenesSeleccionadas; private ObservableCollection<string> _imagenesSeleccionadas;
private bool _closeOK;
[ObservableProperty] [ObservableProperty]
private ObservableCollection<string> listaImagenes; private ObservableCollection<string> listaImagenes;
@ -59,7 +61,7 @@ public partial class SelectPagesViewModel : ObservableObject
[RelayCommand] [RelayCommand]
private void AssignImages() private void AssignImages()
{ {
_closeOK = true;
_window.Close(); _window.Close();
} }
@ -79,4 +81,6 @@ public partial class SelectPagesViewModel : ObservableObject
SelectedImagenes.Clear(); SelectedImagenes.Clear();
} }
public bool CloseOK => _closeOK;
} }