Mejorado de la exportacion a Excel
This commit is contained in:
parent
922a46d616
commit
759ee627e2
145
MainViewModel.cs
145
MainViewModel.cs
|
@ -386,7 +386,8 @@ namespace CtrEditor
|
|||
assignImagesViewModel.Initialize(this, assignImagesWindow);
|
||||
assignImagesWindow.DataContext = assignImagesViewModel;
|
||||
assignImagesWindow.ShowDialog();
|
||||
SaveStateObjetosSimulables();
|
||||
if (assignImagesWindow.DataContext is AssignImagesViewModel dialog && dialog.CloseOK)
|
||||
SaveStateObjetosSimulables();
|
||||
}
|
||||
|
||||
private async Task WaitForUIUpdateAsync()
|
||||
|
@ -398,7 +399,10 @@ namespace CtrEditor
|
|||
|
||||
private async void MultiPageExtractTagsCommand()
|
||||
{
|
||||
var ImagenesSeleccionadas = new ObservableCollection<string>();
|
||||
var ImagenesSeleccionadas = new ObservableCollection<string>
|
||||
{
|
||||
SelectedImage
|
||||
};
|
||||
|
||||
StopSimulation();
|
||||
|
||||
|
@ -408,17 +412,21 @@ namespace CtrEditor
|
|||
selectPagesWindow.DataContext = selectPagesViewModel;
|
||||
selectPagesWindow.ShowDialog();
|
||||
|
||||
foreach (var page in ImagenesSeleccionadas)
|
||||
{
|
||||
SelectedImage = page;
|
||||
await WaitForUIUpdateAsync(); // Espera a que la UI se actualice
|
||||
ExtraerTags();
|
||||
}
|
||||
if (selectPagesWindow.DataContext is SelectPagesViewModel dialog && dialog.CloseOK)
|
||||
foreach (var page in ImagenesSeleccionadas)
|
||||
{
|
||||
SelectedImage = page;
|
||||
await WaitForUIUpdateAsync(); // Espera a que la UI se actualice
|
||||
ExtraerTags();
|
||||
}
|
||||
}
|
||||
|
||||
private async void MultiPageAnalizeCommand()
|
||||
{
|
||||
var ImagenesSeleccionadas = new ObservableCollection<string>();
|
||||
var ImagenesSeleccionadas = new ObservableCollection<string>
|
||||
{
|
||||
SelectedImage
|
||||
};
|
||||
|
||||
StopSimulation();
|
||||
|
||||
|
@ -446,7 +454,8 @@ namespace CtrEditor
|
|||
{
|
||||
foreach (var obj in ObjetosSimulables)
|
||||
if (obj is osBuscarCoincidencias objBC)
|
||||
objBC.BuscarCoincidencias();
|
||||
if (objBC.Show_On_This_Page)
|
||||
objBC.BuscarCoincidencias();
|
||||
|
||||
}
|
||||
|
||||
|
@ -462,7 +471,6 @@ namespace CtrEditor
|
|||
|
||||
try
|
||||
{
|
||||
int colFix = 0;
|
||||
// Crea o abre un libro de Excel.
|
||||
XLWorkbook workbook = File.Exists(filePath) ? new XLWorkbook(filePath) : new XLWorkbook();
|
||||
var sheetName = "TagsExtracted";
|
||||
|
@ -470,53 +478,96 @@ namespace CtrEditor
|
|||
var worksheet = workbook.Worksheets.Contains(sheetName) ? workbook.Worksheet(sheetName) : workbook.Worksheets.Add(sheetName);
|
||||
var lastRowUsed = worksheet.LastRowUsed();
|
||||
// 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.
|
||||
foreach (var obj in ObjetosSimulables)
|
||||
{
|
||||
if (obj is osExtraccionTag objExtraccionTag && (objExtraccionTag.Id_Search_Templates == null || objExtraccionTag.Id_Search_Templates == "") && !objExtraccionTag.Cloned)
|
||||
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)
|
||||
{
|
||||
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 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)
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
col = objExtraccionTag.Collumn_number;
|
||||
if (col == 0 || columnasOcupadas.Contains(col))
|
||||
col = ++actualMaxCol;
|
||||
else
|
||||
actualMaxCol = Math.Max(actualMaxCol, col);
|
||||
|
||||
maxColGroup = Math.Max(maxColGroup, objExtraccionTag.Collumn_number);
|
||||
if (objExtraccionTag.New_Row) row++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
colNextGroup += maxColGroup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Formatear los títulos en la fila 1
|
||||
var titleRow = worksheet.Row(1);
|
||||
titleRow.Style.Font.Bold = true;
|
||||
|
|
|
@ -145,7 +145,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
[property: ReadOnly(true)]
|
||||
float coincidencias;
|
||||
int coincidencias;
|
||||
|
||||
public osBuscarCoincidencias()
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
search_rectangles = new List<Rect>();
|
||||
|
||||
// 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
|
||||
float[] resultArray = result.GetData(false) as float[];
|
||||
|
@ -349,9 +349,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
var objetosSimulables2Copy = new List<osBase>(_mainViewModel.ObjetosSimulables);
|
||||
// Saltar el primer rectángulo en el foreach
|
||||
|
||||
|
||||
|
||||
foreach (var rectangle in search_rectangles.Skip(1))
|
||||
int Row = 0;
|
||||
foreach (var rectangle in search_rectangles) //.Skip(1))
|
||||
{
|
||||
float offsetX = PixelsToMeters((float)rectangle.X) - Left;
|
||||
float offsetY = PixelsToMeters((float)rectangle.Y) - Top;
|
||||
|
@ -368,6 +367,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
if (newObj != null)
|
||||
{
|
||||
newObj.Cloned = true;
|
||||
newObj.Cloned_from = objExtraccionTag.Id;
|
||||
newObj.Copy_Number = Row;
|
||||
newObj.Enable_On_All_Pages = false;
|
||||
if (newObj.Extraer)
|
||||
objExtraccionTag.CaptureImageAreaAndDoOCR();
|
||||
|
@ -375,6 +376,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
}
|
||||
}
|
||||
}
|
||||
Row++;
|
||||
if (newObj != null)
|
||||
newObj.New_Row = true;
|
||||
|
||||
|
|
|
@ -13,15 +13,23 @@
|
|||
</UserControl.DataContext>
|
||||
|
||||
<Canvas>
|
||||
<Rectangle x:Name="Area"
|
||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Opacity="{Binding Opacity_oculto}" Fill="Green"
|
||||
Stroke="Black"
|
||||
|
||||
>
|
||||
<Rectangle.RenderTransform>
|
||||
<RotateTransform Angle="{Binding Angulo}"/>
|
||||
</Rectangle.RenderTransform>
|
||||
<Rectangle x:Name="Area" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Opacity="{Binding Opacity_oculto}" Fill="Green" Stroke="Black">
|
||||
</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>
|
||||
</UserControl>
|
||||
|
|
|
@ -38,6 +38,12 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
[property: Category("Tag Extraction:")]
|
||||
bool cloned;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Autocreated and cloned with Search Templates")]
|
||||
[property: Category("Tag Extraction:")]
|
||||
[property: Hidden]
|
||||
UniqueId cloned_from;
|
||||
|
||||
[ObservableProperty]
|
||||
bool new_Row;
|
||||
|
||||
|
@ -76,7 +82,18 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
ResetTimer();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Layout:")]
|
||||
public float angulo;
|
||||
|
||||
partial void OnAnguloChanged(float value)
|
||||
{
|
||||
ResetTimer();
|
||||
}
|
||||
|
||||
public override void OnTimerAfterMovement() {
|
||||
Angulo = (float)Math.Round(Angulo / 90) * 90;
|
||||
|
||||
if (Extraer)
|
||||
CaptureImageAreaAndDoOCR();
|
||||
}
|
||||
|
@ -110,10 +127,6 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Layout:")]
|
||||
public float angulo;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
string tag_extract;
|
||||
|
@ -131,7 +144,17 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
[property: Category("Export:")]
|
||||
int collumn_number;
|
||||
|
||||
[ObservableProperty]
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
[property: ReadOnly(true)]
|
||||
int copy_Number;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
bool show_Debug_Window;
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
float opacity_oculto;
|
||||
|
||||
public osExtraccionTag()
|
||||
|
@ -144,7 +167,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
|
||||
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)
|
||||
|
|
|
@ -179,57 +179,74 @@ 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)
|
||||
{
|
||||
// Asegurarse de que la imagen origen está disponible
|
||||
if (imagenDeFondo.Source is BitmapSource bitmapSource)
|
||||
{
|
||||
// Obtener los DPI de la imagen original
|
||||
float originalDpiX = (float)bitmapSource.DpiX;
|
||||
float originalDpiY = (float)bitmapSource.DpiY;
|
||||
|
||||
// Estándar DPI en el que el Canvas renderiza la imagen
|
||||
float canvasDpiX = 96; // WPF usually renders at 96 DPI
|
||||
float canvasDpiX = 96;
|
||||
float canvasDpiY = 96;
|
||||
|
||||
// Calcular el ratio de escala entre el Canvas y la imagen original
|
||||
float scaleFactorX = originalDpiX / canvasDpiX;
|
||||
float scaleFactorY = originalDpiY / canvasDpiY;
|
||||
|
||||
// Ajustar las coordenadas de recorte en función del ratio de escala
|
||||
int x = (int)MeterToPixels(Left * scaleFactorX);
|
||||
int y = (int)MeterToPixels(Top * scaleFactorY);
|
||||
int width = (int)MeterToPixels(Ancho * scaleFactorX);
|
||||
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 (y < 0) y = 0;
|
||||
if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
|
||||
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));
|
||||
|
||||
// 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();
|
||||
encoder.Frames.Add(BitmapFrame.Create(croppedBitmap));
|
||||
encoder.Frames.Add(BitmapFrame.Create(transformedBitmap));
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
encoder.Save(memoryStream);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
//ShowPreviewWindow(memoryStream);
|
||||
if (ShowPreview) ShowPreviewWindow(memoryStream);
|
||||
|
||||
// Cargar la imagen en Tesseract desde el MemoryStream
|
||||
using (var img = Pix.LoadFromMemory(memoryStream.ToArray()))
|
||||
using (var engine = new TesseractEngine(@"./Tesseract", "eng", EngineMode.Default))
|
||||
using (var bmp = new System.Drawing.Bitmap(memoryStream))
|
||||
{
|
||||
var result = engine.Process(img);
|
||||
return result.GetText();
|
||||
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))
|
||||
{
|
||||
// Configuraciones para mejorar el OCR de una sola letra
|
||||
engine.SetVariable("tessedit_char_whitelist", " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."); // Lista blanca de caracteres
|
||||
var result = engine.Process(img);
|
||||
return result.GetText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +254,7 @@ namespace CtrEditor.ObjetosSim
|
|||
return "";
|
||||
}
|
||||
|
||||
|
||||
// All Pages Objects
|
||||
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
|
||||
[ObservableProperty]
|
||||
|
@ -817,6 +835,7 @@ namespace CtrEditor.ObjetosSim
|
|||
public class UniqueId
|
||||
{
|
||||
public int Value { get; set; }
|
||||
|
||||
public UniqueId ObtenerNuevaID()
|
||||
{
|
||||
Value = EstadoPersistente.Instance.newid;
|
||||
|
@ -824,13 +843,64 @@ namespace CtrEditor.ObjetosSim
|
|||
Value++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void NoId()
|
||||
{
|
||||
// No ID == NULL
|
||||
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 ItemCollection GetValues()
|
||||
|
|
|
@ -58,13 +58,9 @@
|
|||
</ToolBarTray>
|
||||
|
||||
<!-- Lista de Objetos -->
|
||||
<ListBox x:Name="ListaObjetosSim" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding ObjetosSimulables}"
|
||||
DisplayMemberPath="Nombre" SelectionMode="Multiple">
|
||||
<i:Interaction.Behaviors>
|
||||
<local:SelectedItemsBehavior SelectedItems="{Binding SelectedObjetosSimulables, Mode=TwoWay}" />
|
||||
</i:Interaction.Behaviors>
|
||||
</ListBox>
|
||||
<DataGrid />
|
||||
<xctk:CheckListBox Grid.Row="1" Grid.Column="0" ItemsSource="{Binding ObjetosSimulables}" DisplayMemberPath="Nombre"
|
||||
SelectedItemsOverride="{Binding SelectedObjetosSimulables, Mode=TwoWay}" />
|
||||
|
||||
<!-- Lista de Imágenes con CheckListBox -->
|
||||
<xctk:CheckListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding ListaImagenes}" DisplayMemberPath="."
|
||||
SelectedItemsOverride="{Binding SelectedImagenes, Mode=TwoWay}" />
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using CtrEditor;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Collections;
|
||||
using CtrEditor.ObjetosSim.Extraccion_Datos;
|
||||
using Microsoft.Xaml.Behaviors;
|
||||
|
||||
|
||||
namespace CtrEditor.PopUps
|
||||
|
@ -16,18 +12,19 @@ namespace CtrEditor.PopUps
|
|||
/// Interaction logic for AssignImagesWindow.xaml
|
||||
/// </summary>
|
||||
public partial class AssignImagesWindow : Window
|
||||
{
|
||||
{
|
||||
public AssignImagesWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public partial class AssignImagesViewModel : ObservableObject
|
||||
{
|
||||
private MainViewModel _mainViewModel;
|
||||
private Window _window;
|
||||
|
||||
private bool _closeOK;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<osBase> objetosSimulables;
|
||||
|
||||
|
@ -40,7 +37,11 @@ namespace CtrEditor.PopUps
|
|||
[ObservableProperty]
|
||||
private ObservableCollection<string> selectedImagenes;
|
||||
|
||||
public AssignImagesViewModel() { }
|
||||
public AssignImagesViewModel()
|
||||
{
|
||||
SelectedObjetosSimulables = new ObservableCollection<osBase>();
|
||||
SelectedObjetosSimulables.CollectionChanged += SelectedObjetosSimulables_CollectionChanged;
|
||||
}
|
||||
|
||||
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))));
|
||||
|
||||
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]
|
||||
|
@ -62,7 +81,7 @@ namespace CtrEditor.PopUps
|
|||
objeto.ShowOnThisPagesList = new List<string>(SelectedImagenes);
|
||||
objeto.Show_On_This_Page = objeto.Show_On_This_Page;
|
||||
}
|
||||
|
||||
_closeOK = true;
|
||||
_window.Close();
|
||||
}
|
||||
|
||||
|
@ -97,67 +116,11 @@ namespace CtrEditor.PopUps
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ public partial class SelectPagesViewModel : ObservableObject
|
|||
private Window _window;
|
||||
private ObservableCollection<string> _imagenesSeleccionadas;
|
||||
|
||||
private bool _closeOK;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<string> listaImagenes;
|
||||
|
||||
|
@ -59,7 +61,7 @@ public partial class SelectPagesViewModel : ObservableObject
|
|||
[RelayCommand]
|
||||
private void AssignImages()
|
||||
{
|
||||
|
||||
_closeOK = true;
|
||||
_window.Close();
|
||||
}
|
||||
|
||||
|
@ -79,4 +81,6 @@ public partial class SelectPagesViewModel : ObservableObject
|
|||
SelectedImagenes.Clear();
|
||||
}
|
||||
|
||||
public bool CloseOK => _closeOK;
|
||||
|
||||
}
|
Loading…
Reference in New Issue