diff --git a/MainWindow.xaml b/MainWindow.xaml
index 5b096a5..5cbb1db 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -88,11 +88,13 @@
Grid.Column="2"
Text="{Binding SearchUnidadeText, UpdateSourceTrigger=PropertyChanged}" />
-
+
+
+
+ x:Name="UnidadesListView"
+ PreviewMouseLeftButtonDown="UnidadesListView_PreviewMouseLeftButtonDown"
+ PreviewMouseRightButtonDown="UnidadesListView_PreviewMouseRightButtonDown">
@@ -104,21 +106,107 @@
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index d5d1bb2..331f1f0 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -47,19 +47,27 @@ namespace BD_empresa
if (sender is ListView lv)
{
var pt = e.GetPosition(lv);
- // Se clicou em um ListViewItem, seleciona-o (comportamento útil para context menu)
var hit = VisualTreeHelper.HitTest(lv, pt);
var dep = hit?.VisualHit;
+ if (dep == null) return;
+
+ // Seleciona o item clicado
var lvi = FindAncestor(dep);
- if (lvi != null)
- {
- lvi.IsSelected = true;
- }
+ if (lvi != null) lvi.IsSelected = true;
+
+ // Se certo elemento TextBox foi clicado, foca ele (para permitir seleção/Ctrl+C)
+ var tbx = FindAncestor(dep) ?? FindDescendant(dep);
+ tbx?.Focus();
RecordCellTextFromPoint(lv, pt);
}
}
+ private void UnidadesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ _lastClickedCellText = null;
+ }
+
///
/// Executado quando o usuário pressiona Ctrl+C
///
@@ -88,7 +96,14 @@ namespace BD_empresa
// 1) se o usuário clicou previamente em uma célula (direito/esquerdo), usamos esse texto
if (!string.IsNullOrEmpty(_lastClickedCellText))
{
- Clipboard.SetText(_lastClickedCellText);
+ try
+ {
+ Clipboard.SetText(_lastClickedCellText);
+ }
+ catch (Exception ex)
+{
+ MessageBox.Show($"Erro ao copiar para o clipboard: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
return;
}
@@ -106,7 +121,14 @@ namespace BD_empresa
if (prop != null)
{
var value = prop.GetValue(unidade)?.ToString() ?? string.Empty;
- Clipboard.SetText(value);
+ try
+ {
+ Clipboard.SetText(value);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Erro ao copiar para o clipboard: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
return;
}
}
@@ -115,13 +137,27 @@ namespace BD_empresa
var tb = FindDescendant(lvi);
if (tb != null)
{
- Clipboard.SetText(tb.Text);
+ try
+ {
+ Clipboard.SetText(tb.Text);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Erro ao copiar para o clipboard: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
return;
}
}
// 3) fallback final: ToString do objeto
- Clipboard.SetText(unidade?.ToString() ?? string.Empty);
+ try
+ {
+ Clipboard.SetText(unidade?.ToString() ?? string.Empty);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Erro ao copiar para o clipboard: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
}
}
@@ -136,31 +172,68 @@ namespace BD_empresa
var dep = hit?.VisualHit;
if (dep == null) return;
- // sobe a árvore procurando TextBlock (geralmente GridView cria TextBlock)
- var tb = FindAncestor(dep);
- if (tb != null)
+ // 1) Procura TextBox (nossa célula agora é TextBox readonly)
+ var tbx = FindAncestor(dep) ?? FindDescendant(dep);
+ if (tbx != null)
{
- _lastClickedCellText = tb.Text;
+ // se houver seleção, prioriza a seleção
+ if (!string.IsNullOrEmpty(tbx.SelectedText))
+ _lastClickedCellText = tbx.SelectedText;
+ else
+ _lastClickedCellText = tbx.Text;
return;
}
- // às vezes o TextBlock está abaixo de um Border/ContentPresenter
+ // 2) Procura TextBlock (fallback)
+ var tblock = FindAncestor(dep) ?? FindDescendant(dep);
+ if (tblock != null)
+ {
+ _lastClickedCellText = tblock.Text;
+ return;
+ }
+
+ // 3) Fallback: procura container e, dentro dele, tenta TextBox primeiro, depois TextBlock
DependencyObject? container = FindAncestor(dep);
container ??= FindAncestor(dep);
if (container != null)
{
- var tb2 = FindDescendant(container);
- if (tb2 != null)
+ var innerTbx = FindDescendant(container);
+ if (innerTbx != null)
{
- _lastClickedCellText = tb2.Text;
+ _lastClickedCellText = !string.IsNullOrEmpty(innerTbx.SelectedText) ? innerTbx.SelectedText : innerTbx.Text;
+ return;
+ }
+
+ var innerTblock = FindDescendant(container);
+ if (innerTblock != null)
+ {
+ _lastClickedCellText = innerTblock.Text;
+ return;
+ }
+ }
+
+ // 4) último recurso: se um ListViewItem foi selecionado, tenta pegar a primeira coluna via binding (fallback anterior)
+ if (listView.SelectedItem is Data.UnidadeSmart unidade)
+ {
+ var gv = listView.View as GridView;
+ if (gv?.Columns.Count > 0)
+ {
+ var firstCol = gv.Columns[0];
+ if (firstCol.DisplayMemberBinding is System.Windows.Data.Binding b && !string.IsNullOrEmpty(b.Path?.Path))
+ {
+ var prop = unidade.GetType().GetProperty(b.Path.Path, BindingFlags.Public | BindingFlags.Instance);
+ if (prop != null)
+ {
+ var value = prop.GetValue(unidade)?.ToString() ?? string.Empty;
+ _lastClickedCellText = value;
+ }
+ }
}
}
}
- ///
- /// Encontra primeiro ancestral do tipo T.
- ///
+ // Helpers (coloque-os se já não existirem):
private static T? FindAncestor(DependencyObject? current) where T : DependencyObject
{
while (current != null)
@@ -171,9 +244,6 @@ namespace BD_empresa
return null;
}
- ///
- /// Encontra primeiro descendente do tipo T usando DFS (útil para achar TextBlock dentro de um visual container)
- ///
private static T? FindDescendant(DependencyObject? root) where T : DependencyObject
{
if (root == null) return null;
@@ -192,6 +262,7 @@ namespace BD_empresa
}
return null;
}
+
private void Window_Loaded(object sender, RoutedEventArgs e)
{
txtEmpresaSearch.Focus();
@@ -218,22 +289,110 @@ namespace BD_empresa
}
private void UnidadeListView_EnterKeyDown(object sender, KeyEventArgs e)
{
- if (e.Key == Key.Enter && sender is ListViewItem listViewItem && listViewItem.Content is Data.UnidadeSmart unidade && !string.IsNullOrWhiteSpace(unidade.Caminho_NFs))
+ try
{
- string? parentDirectory = System.IO.Path.GetDirectoryName(unidade.Caminho_NFs);
+ if (e.Key != Key.Enter) { return; }
- if (!string.IsNullOrWhiteSpace(parentDirectory))
+ // DataContext do Button será a UnidadeSmart relacionada à linha
+ var lvi = sender as ListViewItem;
+ if (lvi?.Content is not Data.UnidadeSmart unidade)
{
- try
+ MessageBox.Show("Não foi possível identificar a unidade.", "Erro", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ var caminho = unidade.Caminho_NFs;
+ if (string.IsNullOrWhiteSpace(caminho))
+ {
+ MessageBox.Show("Não há caminho definido para essa unidade.", "Aviso", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ string folderToOpen;
+ // Se o caminho for um arquivo (provavelmente um arquivo NFe), abre o diretório pai.
+ if (System.IO.File.Exists(caminho))
+ {
+ folderToOpen = System.IO.Path.GetDirectoryName(caminho) ?? caminho;
+ }
+ else
+ {
+ // tenta obter diretório do caminho (caso usuário tenha colocado um arquivo inexistente ou caminho parcial)
+ var parent = System.IO.Path.GetDirectoryName(caminho);
+ if (!string.IsNullOrWhiteSpace(parent) && System.IO.Directory.Exists(parent))
+ folderToOpen = parent;
+ else
{
- System.Diagnostics.Process.Start("explorer.exe", unidade.Caminho_NFs);
- }
- catch (System.Exception ex)
- {
- MessageBox.Show($"Não foi possível abrir a pasta: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ MessageBox.Show($"O caminho informado não existe: {caminho}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
}
}
+
+ // Abre o Explorer na pasta encontrada (UseShellExecute = true para abrir paths corretamente)
+ var psi = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = "explorer.exe",
+ Arguments = $"\"{folderToOpen}\"",
+ UseShellExecute = true
+ };
+ System.Diagnostics.Process.Start(psi);
+ }
+ catch (System.Exception ex)
+ {
+ MessageBox.Show($"Não foi possível abrir a pasta: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
+ private void OpenFolderButton_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ // DataContext do Button será a UnidadeSmart relacionada à linha
+ var btn = sender as Button;
+ if (btn?.DataContext is not Data.UnidadeSmart unidade)
+ {
+ MessageBox.Show("Não foi possível identificar a unidade.", "Erro", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ var caminho = unidade.Caminho_NFs;
+ if (string.IsNullOrWhiteSpace(caminho))
+ {
+ MessageBox.Show("Não há caminho definido para essa unidade.", "Aviso", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ string folderToOpen;
+ // Se o caminho for um arquivo (provavelmente um arquivo NFe), abre o diretório pai.
+ if (System.IO.File.Exists(caminho))
+ {
+ folderToOpen = System.IO.Path.GetDirectoryName(caminho) ?? caminho;
+ }
+ else
+ {
+ // tenta obter diretório do caminho (caso usuário tenha colocado um arquivo inexistente ou caminho parcial)
+ var parent = System.IO.Path.GetDirectoryName(caminho);
+ if (!string.IsNullOrWhiteSpace(parent) && System.IO.Directory.Exists(parent))
+ folderToOpen = parent;
+ else
+ {
+ MessageBox.Show($"O caminho informado não existe: {caminho}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+ }
+
+ // Abre o Explorer na pasta encontrada (UseShellExecute = true para abrir paths corretamente)
+ var psi = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = "explorer.exe",
+ Arguments = $"\"{folderToOpen}\"",
+ UseShellExecute = true
+ };
+ System.Diagnostics.Process.Start(psi);
+ }
+ catch (System.Exception ex)
+ {
+ MessageBox.Show($"Não foi possível abrir a pasta: {ex.Message}", "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
}
}
\ No newline at end of file