- Implement ThemeManager for dynamic light/dark theme switching in the application. - Create Wait class for cancellable delays without exceptions for smoother user experience. - Introduce WatchedProductsStore to manage and persist watched products in JSON format. - Add WindowsNotifier for system notifications to inform users of important events. - Develop ProductViewModel to encapsulate product data and manage UI interactions effectively.
815 lines
55 KiB
XML
815 lines
55 KiB
XML
<UserControl x:Class="AutoBidder.Controls.SettingsControl"
|
||
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:ctl="clr-namespace:AutoBidder.Controls"
|
||
mc:Ignorable="d"
|
||
d:DesignHeight="800" d:DesignWidth="1200"
|
||
Background="{DynamicResource Brush.Bg}">
|
||
|
||
<!-- Stili centralizzati in Themes/Controls.xaml -->
|
||
|
||
|
||
<Grid>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="*"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<!-- Scrollable Content -->
|
||
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto">
|
||
<StackPanel Margin="30,20">
|
||
|
||
<!-- SEZIONE 0: Aspetto -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Aspetto"
|
||
Margin="0,0,0,14"
|
||
Help="Scegli il tema dell'interfaccia. Il cambiamento è immediato."/>
|
||
|
||
<StackPanel Orientation="Horizontal">
|
||
<RadioButton x:Name="ThemeDarkRadio"
|
||
Content="Scuro"
|
||
GroupName="AppTheme"
|
||
IsChecked="True"
|
||
Checked="ThemeDarkRadio_Checked"
|
||
ToolTip="Tema scuro (consigliato per sessioni lunghe)"/>
|
||
<RadioButton x:Name="ThemeLightRadio"
|
||
Content="Chiaro"
|
||
GroupName="AppTheme"
|
||
Checked="ThemeLightRadio_Checked"
|
||
ToolTip="Tema chiaro"/>
|
||
</StackPanel>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE 0-bis: Sessione / Autenticazione -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Sessione Bidoo (Autenticazione)"
|
||
Margin="0,0,0,14"
|
||
Help="Accedi dalla scheda Browser: il cookie viene rilevato e importato da solo, e vale per tutta l'applicazione. La sessione resta salvata e protetta con DPAPI, quindi l'accesso non va rifatto a ogni avvio. Un solo modo di accedere e nessun campo per il cookie a mano: due strade vorrebbero dire due sessioni possibili, e la domanda "quale sta usando?" senza risposta."/>
|
||
|
||
<!-- Stato corrente -->
|
||
<Border Background="{DynamicResource Brush.SurfaceAlt}"
|
||
BorderBrush="{DynamicResource Brush.Border}"
|
||
BorderThickness="1"
|
||
CornerRadius="6"
|
||
Padding="12,10"
|
||
Margin="0,0,0,14">
|
||
<StackPanel>
|
||
<TextBlock x:Name="SessionStatusText"
|
||
Text="Non connesso"
|
||
Foreground="{DynamicResource Brush.Danger}"
|
||
FontWeight="SemiBold"/>
|
||
<TextBlock x:Name="SessionStatusDetail"
|
||
Text="Nessuna sessione attiva."
|
||
Foreground="{DynamicResource Brush.TextMuted}"
|
||
FontSize="11.5"
|
||
Margin="0,3,0,0"
|
||
TextWrapping="Wrap"/>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<StackPanel Orientation="Horizontal">
|
||
<Button Content="Apri Browser per il login"
|
||
Background="{DynamicResource Brush.Accent}"
|
||
Foreground="{DynamicResource Brush.TextOnAccent}"
|
||
Style="{StaticResource SmallRoundedButton}"
|
||
Click="OpenBrowserLoginButton_Click"
|
||
Margin="0,0,8,0"/>
|
||
<Button x:Name="ConnectSessionButton"
|
||
Content="Verifica connessione"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Style="{StaticResource SmallRoundedButton}"
|
||
ToolTip="Ricontrolla la sessione salvata contro il sito"
|
||
Click="ConnectSessionButton_Click"
|
||
Margin="0,0,8,0"/>
|
||
<Button x:Name="DisconnectSessionButton"
|
||
Content="Disconnetti"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Style="{StaticResource SmallRoundedButton}"
|
||
Click="DisconnectSessionButton_Click"/>
|
||
</StackPanel>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE 1: Impostazioni Predefinite Aste -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Impostazioni Predefinite Aste"
|
||
Margin="0,0,0,14"
|
||
Help="Valgono per ogni asta nuova che non abbia limiti propri. I limiti scritti nella scheda Prodotti hanno sempre la precedenza su questi."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="150"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Anticipo Puntata (millisecondi)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center" ToolTip="Quanti millisecondi prima della scadenza parte la puntata. È il parametro che decide quanto costa vincere: il motore punta solo nei cicli che arrivano fin qui senza che nessun altro abbia puntato. Dalla rigiocata di 2.095 aste concluse: sotto il secondo basta in mediana 1 puntata per asta, sotto i 2 s ne servono 15, sotto i 3 s 46. Ma sotto i 600 ms un picco di rete fa arrivare la puntata a giochi chiusi (il ping tocca 444 ms nel p99,9). Fascia consigliata: 600–2000 ms. Predefinito 1000."/>
|
||
<TextBox Grid.Row="0" Grid.Column="1" x:Name="DefaultBidBeforeDeadlineMsTextBox" Text="200" Margin="10,10"/>
|
||
|
||
|
||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Prezzo Minimo (€)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="2" Grid.Column="1" x:Name="DefaultMinPriceTextBox" Text="0" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Prezzo Massimo (€)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="3" Grid.Column="1" x:Name="DefaultMaxPriceTextBox" Text="0" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Max Click" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center" ToolTip="Quante puntate al massimo spendere su una singola asta. Entra anche nel calcolo dei limiti consigliati per prodotto: ogni puntata in più è denaro che non si può mettere sul prezzo. 0 = illimitate."/>
|
||
<TextBox Grid.Row="4" Grid.Column="1" x:Name="DefaultMaxClicksTextBox" Text="0" Margin="10,10"/>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Limiti consigliati per prodotto -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Limiti Consigliati per Prodotto"
|
||
Margin="0,0,0,14"
|
||
Help="La scheda Prodotti propone, per ogni articolo, un prezzo minimo e uno massimo ricavati da come sono andate le sue aste finora. Il massimo nasce da due vincoli e vince il più stretto: il prezzo che copre la quota di chiusure impostata qui sotto, e quanto si può spendere — valore del prodotto, meno il costo delle puntate massime. Il minimo è il decimo percentile delle chiusure: sotto quel prezzo l'asta non si chiude quasi mai, quindi puntare lì è quasi sempre speso a vuoto. Perché non basta la moda: il prezzo a cui un articolo si aggiudica più spesso copre fra il 15% e il 44% delle sue aste, a seconda del prodotto. Fermandosi lì si resterebbe fuori dalla maggior parte delle occasioni."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="200"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Copertura delle chiusure (%)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="In quante aste passate saresti stato ancora in gioco fermandoti al massimo consigliato. Alzarla vuol dire restare in corsa più spesso ma spingersi su prezzi più alti; abbassarla vuol dire puntare solo sulle occasioni buone e lasciar perdere le altre. Fascia sensata: 50–95."/>
|
||
<TextBox Grid.Row="0" Grid.Column="1" x:Name="SuggestedCoverageTextBox"
|
||
Text="85" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Costo medio di una puntata (€)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Quanto ti costa una puntata. Serve a calcolare il tetto di spesa: valore del prodotto meno le puntate massime moltiplicate per questo costo."/>
|
||
<TextBox Grid.Row="1" Grid.Column="1" x:Name="AverageBidCostTextBox"
|
||
Text="0,20" Margin="10,10"/>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE 2: Stato Iniziale Aste -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Stato Iniziale Aste"
|
||
Margin="0,0,0,14"
|
||
Help="Come si comportano le aste quando vengono caricate o aggiunte.
|
||
|
||
• Fermata: non viene monitorata fino all'avvio manuale.
|
||
• Osserva: viene seguita (prezzo, scadenza, avversari) ma non punta mai. Utile per studiarla prima di entrare.
|
||
• Attiva: viene monitorata e punta da sola quando serve.
|
||
• Ricorda Stato: ogni asta riprende lo stato che aveva alla chiusura, e sovrascrive le altre opzioni.
|
||
|
||
Consiglio: usa Fermata per caricare senza avviare, poi avvia a mano quelle che vuoi."/>
|
||
|
||
<!-- Stato all'apertura applicazione -->
|
||
<TextBlock Text="Stato aste al caricamento dell'applicazione"
|
||
Style="{StaticResource FieldLabel}"/>
|
||
|
||
<StackPanel Orientation="Horizontal" Margin="0,0,0,20">
|
||
<RadioButton x:Name="LoadAuctionsStopped"
|
||
Content="Fermate"
|
||
GroupName="LoadState"
|
||
IsChecked="True"
|
||
ToolTip="Le aste salvate verranno caricate in stato fermo"/>
|
||
<RadioButton x:Name="LoadAuctionsPaused"
|
||
Content="Osserva"
|
||
GroupName="LoadState"
|
||
ToolTip="Le aste salvate seguiranno prezzo e scadenza senza mai puntare"/>
|
||
<RadioButton x:Name="LoadAuctionsActive"
|
||
Content="Attive"
|
||
GroupName="LoadState"
|
||
ToolTip="Le aste salvate verranno avviate automaticamente all'apertura"/>
|
||
<RadioButton x:Name="LoadAuctionsRemember"
|
||
Content="Ricorda Stato"
|
||
GroupName="LoadState"
|
||
ToolTip="Ogni asta ripristina lo stato che aveva alla chiusura (attiva/pausa/ferma)"/>
|
||
</StackPanel>
|
||
|
||
<!-- Stato nuove aste -->
|
||
<TextBlock Text="Stato iniziale di una nuova asta aggiunta"
|
||
Style="{StaticResource FieldLabel}"/>
|
||
|
||
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
|
||
<RadioButton x:Name="NewAuctionStopped"
|
||
Content="Fermata"
|
||
GroupName="NewAuctionState"
|
||
IsChecked="True"
|
||
ToolTip="Le nuove aste verranno aggiunte in stato fermo"/>
|
||
<RadioButton x:Name="NewAuctionPaused"
|
||
Content="Osserva"
|
||
GroupName="NewAuctionState"
|
||
ToolTip="Le nuove aste seguiranno prezzo e scadenza senza mai puntare"/>
|
||
<RadioButton x:Name="NewAuctionActive"
|
||
Content="Attiva"
|
||
GroupName="NewAuctionState"
|
||
ToolTip="Le nuove aste verranno avviate automaticamente"/>
|
||
</StackPanel>
|
||
|
||
<!-- Info Box -->
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Motore di precisione -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Motore di Precisione"
|
||
Margin="0,0,0,14"
|
||
Help="Ogni asta ha il proprio motore indipendente. Il polling si infittisce solo avvicinandosi alla scadenza: un'asta lontana non consuma richieste inutili, una vicina sì."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="150"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Polling oltre 60s (ms)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center" ToolTip="Cadenza quando la scadenza è lontana"/>
|
||
<TextBox Grid.Row="0" Grid.Column="1" x:Name="PollIntervalFarMsTextBox" Text="2000" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Polling 10-60s (ms)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="1" Grid.Column="1" x:Name="PollIntervalMidMsTextBox" Text="900" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Polling sotto 10s (ms)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="2" Grid.Column="1" x:Name="PollIntervalNearMsTextBox" Text="400" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Polling in finestra critica (ms)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center" ToolTip="Usato solo dalle aste in stato Attiva: in Osserva non c'è puntata da azzeccare"/>
|
||
<TextBox Grid.Row="3" Grid.Column="1" x:Name="PollIntervalCriticalMsTextBox" Text="220" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Ampiezza finestra critica (ms)" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="4" Grid.Column="1" x:Name="CriticalWindowMsTextBox" Text="4000" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="5" Grid.Column="0" Text="Limite richieste al secondo" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center" ToolTip="Le puntate hanno corsia preferenziale e non sono soggette a questo limite"/>
|
||
<TextBox Grid.Row="5" Grid.Column="1" x:Name="MaxRequestsPerSecondTextBox" Text="40" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="6" Grid.Column="0" Text="Timer di sistema a 1 ms" Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center" ToolTip="Senza, ogni attesa può sforare di ~15 ms e l'anticipo perde significato"/>
|
||
<CheckBox Grid.Row="6" Grid.Column="1" x:Name="PrecisionTimerCheckBox" Margin="10,10" VerticalAlignment="Center" IsChecked="True"/>
|
||
</Grid>
|
||
|
||
<Border Style="{StaticResource InfoBox}" Margin="0,15,0,0">
|
||
<StackPanel>
|
||
<TextBlock Text="Diagnostica motore"
|
||
FontWeight="Bold"
|
||
Foreground="{DynamicResource Brush.Accent}"
|
||
Margin="0,0,0,10"/>
|
||
<TextBlock x:Name="EngineDiagnosticsText"
|
||
Text="Monitoraggio non avviato."
|
||
TextWrapping="Wrap"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
FontSize="12"
|
||
LineHeight="18"/>
|
||
</StackPanel>
|
||
</Border>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Prodotti seguiti (aggiunta automatica) -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Prodotti Seguiti (aggiunta automatica)"
|
||
Margin="0,0,0,14"
|
||
Help="Bidoo rimette all'asta lo stesso articolo di continuo. Con la stellina in Esplora segui un prodotto: le aste nuove di quell'articolo entrano nel monitor da sole.
|
||
|
||
Perché il valore consigliato è Osserva: un'asta che entra da sola e comincia subito a puntare spenderebbe puntate vere senza che tu l'abbia mai vista.
|
||
|
||
L'elenco dei prodotti è nella scheda Prodotti: lì ogni articolo ha la stellina e i limiti suoi — prezzo, puntate, orizzonte e stato d'ingresso — che vincono su questi."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="200"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Aggiungi le aste nuove da solo"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<CheckBox Grid.Row="0" Grid.Column="1" x:Name="AutoAddEnabledCheckBox"
|
||
Margin="10,10" VerticalAlignment="Center" IsChecked="True"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Stato delle aste aggiunte"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Con cosa entrano nel monitor le aste trovate dalla sorveglianza"/>
|
||
<ComboBox Grid.Row="1" Grid.Column="1" x:Name="AutoAddStateCombo"
|
||
Margin="10,10" VerticalAlignment="Center">
|
||
<ComboBoxItem Content="Osserva (consigliato)" Tag="Watch"/>
|
||
<ComboBoxItem Content="Ferma" Tag="Stopped"/>
|
||
<ComboBoxItem Content="Attiva — punta subito" Tag="Active"/>
|
||
</ComboBox>
|
||
|
||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Cerca aste nuove ogni (secondi)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="2" Grid.Column="1" x:Name="AutoAddScanSecondsTextBox"
|
||
Text="90" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Massimo aste aggiunte insieme"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="0 = nessun limite"/>
|
||
<TextBox Grid.Row="3" Grid.Column="1" x:Name="AutoAddMaxAuctionsTextBox"
|
||
Text="20" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Solo se cominciano entro (minuti)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Un'asta che comincia oltre questo tempo non viene aggiunta ancora: verrà ripresa alla scansione successiva, quando sarà più vicina. Serve a non riempire il monitor di aste che non succederanno per mezza giornata, consumando il tetto qui sopra. A mano puoi sempre aggiungere qualunque asta. 0 = nessun limite."/>
|
||
<TextBox Grid.Row="4" Grid.Column="1" x:Name="AutoAddMaxStartMinutesTextBox"
|
||
Text="60" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="5" Grid.Column="0" Text="Solo aste non ancora cominciate"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Aggiungi da solo soltanto le aste su cui nessuno ha ancora puntato, per poterle seguire dal primo istante all'ultimo. Un'asta presa a metà si può seguire, ma la sua storia è già scritta per buona parte: non si sa quanto è durata davvero, chi c'era prima, come è salito il prezzo. Le statistiche che ne escono sono monche e i dossier raccontano solo la seconda metà. Il prezzo da pagare è che si perdono le occasioni già in corso."/>
|
||
<CheckBox Grid.Row="5" Grid.Column="1" x:Name="AutoAddOnlyNotStartedCheckBox"
|
||
Margin="10,10" VerticalAlignment="Center"/>
|
||
|
||
<TextBlock Grid.Row="6" Grid.Column="0" Text="Quante aste percorrere nella ricerca"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Il listato è ordinato per scadenza: le aste che devono ancora aprire stanno in fondo. Un valore alto è ciò che permette di prenderle prima che inizino. Abbassarlo fa risparmiare richieste, ma le aste vengono prese solo quando sono già cominciate."/>
|
||
<TextBox Grid.Row="6" Grid.Column="1" x:Name="AutoAddScanDepthTextBox"
|
||
Text="2500" Margin="10,10"/>
|
||
</Grid>
|
||
|
||
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Anticipo puntata - misura e taratura -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Anticipo Puntata (misura e taratura)"
|
||
Margin="0,0,0,14"
|
||
Help="L'anticipo impostato è una scommessa; quello che conta è dove la puntata arriva davvero. L'applicazione misura ogni puntata riuscita e, con abbastanza dati, dice se c'è margine per correggere.
|
||
|
||
Dalla rigiocata di 2.095 aste concluse: con anticipo sotto il secondo serve in mediana 1 puntata per asta, sotto i 2 s ne servono 15, sotto i 3 s 46. Dall'altro lato il ping tocca 444 ms nel p99,9, quindi sotto i 600 ms la puntata rischia di arrivare a giochi chiusi. La fascia sensata è 600–2000 ms."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="200"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Misura l'anticipo effettivo"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<CheckBox Grid.Row="0" Grid.Column="1" x:Name="BidLeadTrackingCheckBox"
|
||
Margin="10,10" VerticalAlignment="Center" IsChecked="True"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Proponi correzioni"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Il consiglio non viene mai applicato da solo"/>
|
||
<CheckBox Grid.Row="1" Grid.Column="1" x:Name="BidLeadSuggestionsCheckBox"
|
||
Margin="10,10" VerticalAlignment="Center" IsChecked="True"/>
|
||
|
||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Puntate minime per un consiglio"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="2" Grid.Column="1" x:Name="BidLeadMinSamplesTextBox"
|
||
Text="15" Margin="10,10"/>
|
||
</Grid>
|
||
|
||
<Border Style="{StaticResource InfoBox}" Margin="0,12,0,10">
|
||
<StackPanel>
|
||
<TextBlock Text="Misure raccolte" FontWeight="Bold"
|
||
Foreground="{DynamicResource Brush.Accent}" Margin="0,0,0,8"/>
|
||
<TextBlock x:Name="BidLeadSummaryText" TextWrapping="Wrap"
|
||
Foreground="{DynamicResource Brush.Text}" FontSize="12" LineHeight="18"
|
||
Text="Nessuna puntata registrata finora."/>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<StackPanel Orientation="Horizontal">
|
||
<Button Content="Calcola consiglio" Style="{StaticResource SmallRoundedButton}"
|
||
Background="{DynamicResource Brush.Accent}"
|
||
Foreground="{DynamicResource Brush.TextOnAccent}"
|
||
Margin="0,0,8,0" Click="ComputeBidLeadAdviceButton_Click"/>
|
||
<Button Content="Azzera misure" Style="{StaticResource SmallRoundedButton}"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Foreground="{DynamicResource Brush.Danger}"
|
||
Click="ClearBidLeadStatsButton_Click"/>
|
||
</StackPanel>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Aste programmate -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Aste Programmate"
|
||
Margin="0,0,0,14"
|
||
Help="Un'asta che comincia fra ore non va interrogata ogni due secondi: fino all'apertura non succede nulla. La cadenza si allarga in proporzione all'attesa e torna normale poco prima dell'inizio, così il motore è comunque pronto a puntare."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="200"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Rallenta prima dell'apertura"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<CheckBox Grid.Row="0" Grid.Column="1" x:Name="ScheduledBackoffCheckBox"
|
||
Margin="10,10" VerticalAlignment="Center" IsChecked="True"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Oltre un'ora, ogni (secondi)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="1" Grid.Column="1" x:Name="ScheduledPollFarTextBox"
|
||
Text="1200" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Fra 10 e 60 minuti, ogni (secondi)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"/>
|
||
<TextBox Grid.Row="2" Grid.Column="1" x:Name="ScheduledPollMidTextBox"
|
||
Text="120" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Torna normale (secondi prima)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Margine di sicurezza per non perdere l'apertura"/>
|
||
<TextBox Grid.Row="3" Grid.Column="1" x:Name="ScheduledPollWakeTextBox"
|
||
Text="120" Margin="10,10"/>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Notifiche -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Notifiche"
|
||
Margin="0,0,0,14"
|
||
Help="Avvisi di Windows per gli eventi che vale la pena vedere anche a finestra chiusa."/>
|
||
|
||
<CheckBox x:Name="NotifyOnWinCheckBox" Content="Avvisami quando vinco un'asta"
|
||
IsChecked="True" Margin="0,4"/>
|
||
<CheckBox x:Name="NotifyOnLossCheckBox"
|
||
Content="Avvisami anche quando perdo un'asta su cui avevo puntato"
|
||
Margin="0,4"/>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Cartelle dei dati -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Cartelle dei Dati"
|
||
Margin="0,0,0,14"
|
||
Help="Ogni campo mostra il percorso in uso: cambialo per spostare i dati altrove, svuotalo per tornare alla posizione predefinita. Impostazioni e sessione restano sempre nella cartella dell'applicazione, perché è lì che si legge dove stanno tutti gli altri."/>
|
||
|
||
<TextBlock Text="Dati d'esercizio (aste monitorate, prodotti seguiti)"
|
||
Style="{StaticResource FieldLabel}"/>
|
||
<Grid Margin="0,0,0,12">
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="*"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
</Grid.ColumnDefinitions>
|
||
<TextBox Grid.Column="0" x:Name="DataFolderTextBox"/>
|
||
<Button Grid.Column="1" Content="Sfoglia…" Margin="8,0,0,0"
|
||
Style="{StaticResource SmallRoundedButton}"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Click="BrowseDataFolderButton_Click"/>
|
||
<Button Grid.Column="2" Margin="6,0,0,0"
|
||
Style="{StaticResource IconButton}"
|
||
ToolTip="Apri questa cartella"
|
||
Click="OpenDataFolderButton_Click">
|
||
<TextBlock FontFamily="Segoe MDL2 Assets" Text=""/>
|
||
</Button>
|
||
</Grid>
|
||
|
||
<TextBlock Text="Storico ed esportazioni" Style="{StaticResource FieldLabel}"/>
|
||
<Grid Margin="0,0,0,12">
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="*"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
</Grid.ColumnDefinitions>
|
||
<TextBox Grid.Column="0" x:Name="StatsFolderTextBox"/>
|
||
<Button Grid.Column="1" Content="Sfoglia…" Margin="8,0,0,0"
|
||
Style="{StaticResource SmallRoundedButton}"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Click="BrowseStatsFolderButton_Click"/>
|
||
<Button Grid.Column="2" Margin="6,0,0,0"
|
||
Style="{StaticResource IconButton}"
|
||
ToolTip="Apri questa cartella"
|
||
Click="OpenStatsFolderSettingsButton_Click">
|
||
<TextBlock FontFamily="Segoe MDL2 Assets" Text=""/>
|
||
</Button>
|
||
</Grid>
|
||
|
||
<TextBlock Text="Registri (log applicativo, riscatto puntate, dossier delle aste)"
|
||
Style="{StaticResource FieldLabel}"/>
|
||
<Grid Margin="0,0,0,12">
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="*"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
</Grid.ColumnDefinitions>
|
||
<TextBox Grid.Column="0" x:Name="LogFolderTextBox"/>
|
||
<Button Grid.Column="1" Content="Sfoglia…" Margin="8,0,0,0"
|
||
Style="{StaticResource SmallRoundedButton}"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Click="BrowseLogFolderButton_Click"/>
|
||
<Button Grid.Column="2" Margin="6,0,0,0"
|
||
Style="{StaticResource IconButton}"
|
||
ToolTip="Apri questa cartella"
|
||
Click="OpenLogFolderButton_Click">
|
||
<TextBlock FontFamily="Segoe MDL2 Assets" Text=""/>
|
||
</Button>
|
||
</Grid>
|
||
|
||
<CheckBox x:Name="DetailedStatsCheckBox" IsChecked="True" Margin="0,0,0,6"
|
||
Content="Registra una scheda dettagliata per ogni asta conclusa (serie prezzi, puntate per utente, durata)"/>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Registri su file -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Registri su file"
|
||
Margin="0,0,0,14"
|
||
Help="I registri si scrivono mentre l'applicazione lavora, non alla chiusura: quello che vedi nelle schede è già sul disco. Servono a rileggere cosa è successo mentre non guardavi — e il dossier delle aste è il materiale su cui si studiano le strategie, perché Bidoo non espone nulla di tutto questo a posteriori. È anche ciò che legge backtest.ps1 per dire quanto costerebbe ciascun anticipo."/>
|
||
|
||
<CheckBox x:Name="WriteAppLogCheckBox" IsChecked="True" Margin="0,4"
|
||
Content="Registro applicativo su file (un file per giorno)"/>
|
||
<CheckBox x:Name="WriteFreeBidsLogCheckBox" IsChecked="True" Margin="0,4"
|
||
Content="Registro del riscatto puntate su file"/>
|
||
<CheckBox x:Name="WriteDossiersCheckBox" IsChecked="True" Margin="0,4"
|
||
Content="Dossier per ogni asta (eventi, puntate di ogni utente, ping)"/>
|
||
<CheckBox x:Name="RawPollsCheckBox" IsChecked="True" Margin="0,4"
|
||
Content="Nel dossier registra anche ogni singola interrogazione a Bidoo"
|
||
ToolTip="Risoluzione massima: prezzo, timer e ping a ogni poll. Nella finestra critica sono quattro righe al secondo, quindi i file crescono in fretta."/>
|
||
|
||
<Grid Margin="0,10,0,0">
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="200"/>
|
||
</Grid.ColumnDefinitions>
|
||
|
||
<TextBlock Grid.Column="0" Text="Cancella i registri dopo (giorni)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10"
|
||
VerticalAlignment="Center"
|
||
ToolTip="0 = tienili per sempre"/>
|
||
<TextBox Grid.Column="1" x:Name="LogRetentionTextBox" Text="90" Margin="10,10"/>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE: Catalogo Esplora -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Catalogo (scheda Esplora)"
|
||
Margin="0,0,0,14"
|
||
Help="L'app scende nel listato pagina per pagina, come il sito quando scorri verso il basso: cinquanta aste per richiesta, fino al tetto impostato qui. L'ordine è per scadenza, quindi le prime pagine sono le aste che chiudono prima. Alzare il tetto allarga la vista ma aggiunge una richiesta ogni cinquanta aste."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="200"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Aste da caricare per categoria"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Da 20 a 5000. Una richiesta ogni 50 aste; le categorie piccole finiscono prima e si fermano da sole."/>
|
||
<TextBox Grid.Row="0" Grid.Column="1" x:Name="CatalogMaxAuctionsTextBox"
|
||
Text="500" Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Aggiorna prezzi mentre guardi"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="Acceso, prezzi e timer cambiano sotto gli occhi mentre stai leggendo"/>
|
||
<CheckBox Grid.Row="1" Grid.Column="1" x:Name="CatalogAutoRefreshCheckBox"
|
||
Margin="10,10" VerticalAlignment="Center"/>
|
||
|
||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Riusa le aste scaricate per (secondi)"
|
||
Foreground="{DynamicResource Brush.Text}" Margin="0,10" VerticalAlignment="Center"
|
||
ToolTip="0 = nessuna cache. Evita di riscaricare tutte le pagine a ogni cambio categoria."/>
|
||
<TextBox Grid.Row="2" Grid.Column="1" x:Name="CatalogCacheSecondsTextBox"
|
||
Text="60" Margin="10,10"/>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE 3: Protezione Account -->
|
||
<Border Style="{StaticResource CardBlock}">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Protezione Account"
|
||
Margin="0,0,0,14"
|
||
Help="Tiene da parte un cuscinetto di puntate sull'account.
|
||
|
||
Se il valore è maggiore di zero, il sistema non punta quando le puntate residue scenderebbero sotto la soglia. Nel banner principale compare un indicatore: verde oltre le +10 dal limite, giallo entro 10, rosso al limite o sotto (puntate bloccate). Zero = nessun limite."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="150"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<!-- Puntate Minime da Mantenere -->
|
||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||
Text="Puntate Minime da Mantenere"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Margin="0,10"
|
||
VerticalAlignment="Center"
|
||
ToolTip="Numero minimo di puntate residue da mantenere sull'account. Se > 0, non punterà se scende sotto questa soglia (0 = nessun limite)"/>
|
||
<TextBox Grid.Row="0" Grid.Column="1"
|
||
x:Name="MinimumRemainingBidsTextBox"
|
||
Text="0"
|
||
Margin="10,10"/>
|
||
</Grid>
|
||
|
||
<!-- Info Box -->
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE 4: Limiti Log -->
|
||
<Border Background="{DynamicResource Brush.Surface}"
|
||
BorderBrush="{DynamicResource Brush.Border}"
|
||
BorderThickness="1"
|
||
CornerRadius="4"
|
||
Padding="20">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Limiti Log"
|
||
Margin="0,0,0,14"
|
||
Help="Quante righe di registro tenere in memoria. Le più vecchie vengono scartate al raggiungimento del limite.
|
||
|
||
Valori bassi = meno memoria, meno storico a video. Valori alti = più storico, più memoria. Consigliati: 500–1000 per asta, 1000–2000 per il registro globale.
|
||
|
||
Riguarda solo la memoria: sul file i registri vengono scritti comunque per intero."/>
|
||
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="250"/>
|
||
<ColumnDefinition Width="150"/>
|
||
</Grid.ColumnDefinitions>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||
Text="Max Righe Log per Asta"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Margin="0,10"
|
||
VerticalAlignment="Center"
|
||
ToolTip="Numero massimo di righe di log da mantenere per ogni singola asta (raccomandato: 500-1000)"/>
|
||
<TextBox Grid.Row="0" Grid.Column="1"
|
||
x:Name="MaxLogLinesPerAuctionTextBox"
|
||
Text="500"
|
||
Margin="10,10"/>
|
||
|
||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||
Text="Max Righe Log Globale"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Margin="0,10"
|
||
VerticalAlignment="Center"
|
||
ToolTip="Numero massimo di righe di log da mantenere nel log globale dell'applicazione (raccomandato: 1000-2000)"/>
|
||
<TextBox Grid.Row="1" Grid.Column="1"
|
||
x:Name="MaxGlobalLogLinesTextBox"
|
||
Text="1000"
|
||
Margin="10,10"/>
|
||
|
||
<!-- 📊 NUOVO: Max Storia Puntate -->
|
||
<TextBlock Grid.Row="2" Grid.Column="0"
|
||
Text="Max Puntate da Visualizzare"
|
||
Foreground="{DynamicResource Brush.Text}"
|
||
Margin="0,10"
|
||
VerticalAlignment="Center"
|
||
ToolTip="Numero massimo di puntate da mostrare nella scheda Storia Puntate (raccomandato: 20-50, 0 = tutte)"/>
|
||
<TextBox Grid.Row="2" Grid.Column="1"
|
||
x:Name="MaxBidHistoryEntriesTextBox"
|
||
Text="20"
|
||
Margin="10,10"/>
|
||
</Grid>
|
||
|
||
<!-- Info Box -->
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- SEZIONE 5: Livello di Dettaglio Log -->
|
||
<Border Background="{DynamicResource Brush.Surface}"
|
||
BorderBrush="{DynamicResource Brush.Border}"
|
||
BorderThickness="1"
|
||
CornerRadius="4"
|
||
Padding="20"
|
||
Margin="0,20,0,0">
|
||
<StackPanel>
|
||
<ctl:HelpHeader Title="Livello di Dettaglio Log"
|
||
Margin="0,0,0,14"
|
||
Help="Livello minimo dei messaggi mostrati a video. Il file di registro li riceve tutti comunque, perché serve proprio quando il messaggio utile è uno di quelli nascosti.
|
||
|
||
• Solo Errori: in esercizio, per vedere solo i problemi critici.
|
||
• Normale: uso giornaliero. Errori e avvisi importanti.
|
||
• Informativo: segue le operazioni principali (aste aggiunte, puntate).
|
||
• Debug: parametri delle chiamate e valori interni.
|
||
• Trace: ogni singola chiamata. Molto verboso.
|
||
|
||
Colori: rosso = errori, arancione = avvisi, blu = informazioni, verde = operazioni riuscite, magenta = debug, grigio = trace."/>
|
||
|
||
<!-- Radio Buttons per livello log -->
|
||
<StackPanel>
|
||
<RadioButton x:Name="LogLevelErrorOnly"
|
||
Content="Solo Errori"
|
||
GroupName="LogLevel"
|
||
Margin="0,5"
|
||
ToolTip="Mostra solo errori critici (uso minimo per produzione)"/>
|
||
|
||
<RadioButton x:Name="LogLevelNormal"
|
||
Content="Normale (Errori + Avvisi)"
|
||
GroupName="LogLevel"
|
||
IsChecked="True"
|
||
Margin="0,5"
|
||
ToolTip="Mostra errori e avvisi (uso giornaliero raccomandato)"/>
|
||
|
||
<RadioButton x:Name="LogLevelInformational"
|
||
Content="Informativo (Include operazioni completate)"
|
||
GroupName="LogLevel"
|
||
Margin="0,5"
|
||
ToolTip="Mostra anche messaggi informativi e conferme (uso dettagliato)"/>
|
||
|
||
<RadioButton x:Name="LogLevelDebug"
|
||
Content="Debug (Include dettagli tecnici)"
|
||
GroupName="LogLevel"
|
||
Margin="0,5"
|
||
ToolTip="Mostra anche messaggi di debug per sviluppo"/>
|
||
|
||
<RadioButton x:Name="LogLevelTrace"
|
||
Content="Trace (Tutto - molto verboso)"
|
||
GroupName="LogLevel"
|
||
Margin="0,5"
|
||
ToolTip="Mostra ogni singola operazione (debug avanzato)"/>
|
||
</StackPanel>
|
||
|
||
<!-- Info Box -->
|
||
</StackPanel>
|
||
</Border>
|
||
</StackPanel>
|
||
</ScrollViewer>
|
||
|
||
<!-- Fixed Bottom Bar with Save/Cancel -->
|
||
<Border Grid.Row="1"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
BorderBrush="{DynamicResource Brush.Border}"
|
||
BorderThickness="0,1,0,0"
|
||
Padding="30,15">
|
||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||
<Button Content="Salva"
|
||
Background="{DynamicResource Brush.Success}"
|
||
Style="{StaticResource ModernButton}"
|
||
Margin="0,0,10,0"
|
||
Padding="40,10"
|
||
Click="SaveAllSettings_Click" Foreground="{DynamicResource Brush.TextOnAccent}"/>
|
||
|
||
<Button Content="Annulla"
|
||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||
Style="{StaticResource ModernButton}"
|
||
Padding="40,10"
|
||
Click="CancelAllSettings_Click"/>
|
||
</StackPanel>
|
||
</Border>
|
||
</Grid>
|
||
</UserControl>
|