Nella scheda Prodotti c'è il pulsante che rilegge tutto lo storico e rifà da capo i numeri di ogni articolo: aste viste, prezzo minimo, massimo e medio, puntate del vincitore, vittorie, osservazioni. I limiti scritti a mano e la stellina non cambiano. Il ricalcolo si costruisce da parte e sostituisce le schede solo alla fine: un annullamento a metà lascia quelle di prima. Ogni operazione massiva passa da una finestra di avanzamento (ProgressDialog): titolo, a che punto si è, barra, conto fatto/totale, tempo passato e Annulla. Modale quando è questione di secondi, altrimenti si continua a usare l'applicazione: il recupero delle puntate dei vincitori e lo studio delle aste vanno piano di proposito. La scheda Apprendimento ha un menu di operazioni: studiare le aste chiuse non ancora apprese (lo studio all'avvio si ferma dopo qualche minuto, questo va in fondo), ricostruire il profilo per prodotto e fascia oraria, rifare il bandit dalle decisioni registrate, azzerare lo sfidante o la calibrazione, ricominciare da capo. Lo studio delle aste è una sola routine con budget di tempo facoltativo, avanzamento e annullamento; quello che è già studiato resta studiato. Le barre in alto di tutte le schede hanno la stessa altezza (stile TabToolbar): passando da una scheda all'altra i pulsanti restano allo stesso posto. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
469 lines
33 KiB
XML
469 lines
33 KiB
XML
<UserControl x:Class="AutoBidder.Controls.ProductsControl"
|
|
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:vm="clr-namespace:AutoBidder.ViewModels"
|
|
mc:Ignorable="d"
|
|
d:DesignHeight="800" d:DesignWidth="1200"
|
|
Background="{DynamicResource Brush.Bg}">
|
|
|
|
<UserControl.Resources>
|
|
<Style x:Key="Glyph" TargetType="TextBlock">
|
|
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
|
</Style>
|
|
|
|
<!-- ═══ Modificabile o no: deve vedersi a colpo d'occhio ═══
|
|
Le celle che si possono scrivere hanno il riquadro di una casella di testo;
|
|
le statistiche restano testo semplice e smorzato. Senza questa differenza la
|
|
griglia sembra tutta uguale e non si capisce dove si può intervenire. -->
|
|
<Style x:Key="EditableCell" TargetType="DataGridCell">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Text}"/>
|
|
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
|
<Setter Property="Cursor" Value="IBeam"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="DataGridCell">
|
|
<Border x:Name="box"
|
|
Background="{DynamicResource Brush.Bg}"
|
|
BorderBrush="{DynamicResource Brush.Border}"
|
|
BorderThickness="1"
|
|
CornerRadius="5"
|
|
Margin="3,3"
|
|
Padding="6,0">
|
|
<ContentPresenter VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="box" Property="BorderBrush"
|
|
Value="{DynamicResource Brush.BorderStrong}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEditing" Value="True">
|
|
<Setter TargetName="box" Property="BorderBrush"
|
|
Value="{DynamicResource Brush.Accent}"/>
|
|
<Setter TargetName="box" Property="Background"
|
|
Value="{DynamicResource Brush.Surface}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Il pennino segnala nell'intestazione le colonne che accettano scrittura -->
|
|
<DataTemplate x:Key="EditableHeader">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
|
|
<TextBlock FontFamily="Segoe MDL2 Assets" Text="" FontSize="9"
|
|
Margin="5,0,0,0" VerticalAlignment="Center"
|
|
Foreground="{DynamicResource Brush.Accent}"/>
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
|
|
<!-- Numeri modificabili: allineati a destra, colore pieno -->
|
|
<Style x:Key="EditableText" TargetType="TextBlock">
|
|
<Setter Property="HorizontalAlignment" Value="Right"/>
|
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Text}"/>
|
|
</Style>
|
|
|
|
<!-- Statistiche: sola lettura, quindi smorzate -->
|
|
<Style x:Key="StatText" TargetType="TextBlock">
|
|
<Setter Property="HorizontalAlignment" Value="Right"/>
|
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.TextMuted}"/>
|
|
</Style>
|
|
|
|
<!-- Statistiche estese: il numero da solo non basta, il dettaglio (quartili,
|
|
campione verificato, frequenza) sta nel suggerimento. -->
|
|
<Style x:Key="StatsText" TargetType="TextBlock" BasedOn="{StaticResource StatText}">
|
|
<Setter Property="ToolTip" Value="{Binding StatsExplanation}"/>
|
|
</Style>
|
|
|
|
<!-- Valore, costo reale e risparmio: il ragionamento sta nel suggerimento.
|
|
In rosso quando vincere costa piu' che comprare: e' il caso che va visto
|
|
subito, non nascosto in mezzo agli altri numeri. -->
|
|
<Style x:Key="ValueText" TargetType="TextBlock" BasedOn="{StaticResource StatText}">
|
|
<Setter Property="ToolTip" Value="{Binding ValueExplanation}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding HasSavings}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Success}"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding SavingsIsNegative}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Danger}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
|
|
<!-- Limiti consigliati: il numero da solo non basta, il ragionamento sta nel
|
|
suggerimento. In arancione quando il tetto non copre il prezzo tipico:
|
|
è il caso in cui l'articolo, con quelle puntate, non conviene. -->
|
|
<Style x:Key="AdviceText" TargetType="TextBlock" BasedOn="{StaticResource StatText}">
|
|
<Setter Property="ToolTip" Value="{Binding AdviceExplanation}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Info}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding HasAdvice}" Value="False">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.TextFaint}"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding AdviceWarns}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Warning}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</UserControl.Resources>
|
|
|
|
<Grid>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="*"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- ═══ Barra strumenti ═══ -->
|
|
<Border Grid.Row="0" Style="{StaticResource TabToolbar}">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
|
<Button x:Name="RefreshButton" Style="{StaticResource IconButton}"
|
|
ToolTip="Ricarica elenco e statistiche" Click="RefreshButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<TextBlock Text="Prodotti" FontWeight="SemiBold" Margin="8,0,0,0"
|
|
FontSize="{StaticResource Font.Size.Lg}"
|
|
Foreground="{DynamicResource Brush.Text}" VerticalAlignment="Center"/>
|
|
<Border Width="1" Background="{DynamicResource Brush.Border}" Margin="10,4"/>
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
|
|
<Border Style="{StaticResource Pill}" ToolTip="Prodotti in elenco">
|
|
<TextBlock x:Name="ProductsCountText" Text="0 prodotti"
|
|
FontSize="{StaticResource Font.Size.Sm}"
|
|
Foreground="{DynamicResource Brush.TextMuted}"/>
|
|
</Border>
|
|
<Border Style="{StaticResource Pill}" ToolTip="Prodotti con la stellina accesa">
|
|
<TextBlock x:Name="ProductsWatchedText" Text="0 seguiti"
|
|
FontSize="{StaticResource Font.Size.Sm}"
|
|
Foreground="{DynamicResource Brush.Gold}"/>
|
|
</Border>
|
|
</StackPanel>
|
|
|
|
<!-- Ricerca -->
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center"
|
|
Margin="14,0,10,0">
|
|
<Border Background="{DynamicResource Brush.Bg}"
|
|
BorderBrush="{DynamicResource Brush.Border}" BorderThickness="1"
|
|
CornerRadius="6" Padding="8,0" Margin="0,0,12,0"
|
|
VerticalAlignment="Center">
|
|
<Grid Width="230">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Style="{StaticResource Glyph}" Text="" FontSize="12"
|
|
Foreground="{DynamicResource Brush.TextFaint}" Margin="0,0,6,0"/>
|
|
<TextBox x:Name="SearchBox" Width="196" BorderThickness="0"
|
|
Background="Transparent" VerticalAlignment="Center"
|
|
Foreground="{DynamicResource Brush.Text}"
|
|
TextChanged="SearchBox_TextChanged"
|
|
ToolTip="Filtra i prodotti per nome mentre scrivi"/>
|
|
</StackPanel>
|
|
|
|
<!-- Testo guida: sparisce appena si scrive qualcosa -->
|
|
<TextBlock x:Name="SearchPlaceholder" Text="Cerca un prodotto…"
|
|
IsHitTestVisible="False" Margin="20,0,0,0"
|
|
VerticalAlignment="Center"
|
|
FontSize="{StaticResource Font.Size.Sm}"
|
|
Foreground="{DynamicResource Brush.TextFaint}"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
|
|
<!-- Solo icone, come nel monitor: il tooltip dice esattamente cosa succede. -->
|
|
<StackPanel Grid.Column="3" Orientation="Horizontal" VerticalAlignment="Center">
|
|
<Button x:Name="ScanNowButton" Style="{StaticResource IconButton}"
|
|
Foreground="{DynamicResource Brush.Accent}"
|
|
ToolTip="Cerca aste ora. Interroga subito il catalogo di Bidoo per i prodotti con la stellina accesa e mette nel monitor le aste nuove che trova, con i limiti del prodotto. Senza aspettare il prossimo giro automatico."
|
|
Click="ScanNowButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="ReapplyButton" Style="{StaticResource IconButton}"
|
|
Foreground="{DynamicResource Brush.Accent}"
|
|
ToolTip="Riapplica i limiti. Riscrive prezzo minimo e massimo, puntate massime, avvio e valore reale del prodotto selezionato sulle aste di quel prodotto già presenti nel monitor. Serve dopo aver cambiato i limiti in questa scheda."
|
|
Click="ReapplyButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
|
|
<Border Width="1" Background="{DynamicResource Brush.Border}" Margin="6,4"/>
|
|
|
|
<Button x:Name="RecalculateButton" Style="{StaticResource IconButton}"
|
|
ToolTip="Ricalcola dallo storico. Rilegge tutte le aste concluse dello storico e rifà da capo i numeri di ogni prodotto in elenco: aste viste, prezzo minimo, massimo e medio, puntate del vincitore, vittorie, osservazioni. I limiti scritti a mano e la stellina non cambiano; cambiano i numeri, e quindi i limiti consigliati. Mostra l'avanzamento e si può annullare."
|
|
Click="RecalculateButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="ApplySuggestedButton" Style="{StaticResource IconButton}"
|
|
ToolTip="Usa i limiti consigliati sul prodotto selezionato. Scrive prezzo minimo e massimo consigliati dallo storico: il massimo copre l'85% delle chiusure passate (regolabile in Impostazioni), abbassato se il budget non lo regge — valore del prodotto meno il costo delle puntate massime. Il minimo è il decimo percentile: sotto quel prezzo l'asta non si chiude quasi mai."
|
|
Click="ApplySuggestedButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="ApplyAllSuggestedButton" Style="{StaticResource IconButton}"
|
|
ToolTip="Usa i limiti consigliati su tutti i prodotti. Scrive i limiti consigliati su ogni prodotto che ha abbastanza aste concluse per ricavarli. Chiede conferma e dice prima quante righe cambierebbe."
|
|
Click="ApplyAllSuggestedButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
|
|
<Border Width="1" Background="{DynamicResource Brush.Border}" Margin="6,4"/>
|
|
|
|
<Button x:Name="RemoveButton" Style="{StaticResource IconButton}"
|
|
Foreground="{DynamicResource Brush.Danger}"
|
|
ToolTip="Togli il prodotto selezionato. Lo elimina dall'elenco con i suoi limiti. Le aste già nel monitor restano dove sono; le statistiche del prodotto restano."
|
|
Click="RemoveButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="UnwatchAllButton" Style="{StaticResource IconButton}"
|
|
ToolTip="Spegni tutte le stelline. Nessun prodotto viene più cercato in automatico. I prodotti restano in elenco con i loro limiti: si riaccendono una a una."
|
|
Click="UnwatchAllButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="RemoveUnwatchedButton" Style="{StaticResource IconButton}"
|
|
Foreground="{DynamicResource Brush.Danger}"
|
|
ToolTip="Togli i prodotti senza stellina. Elimina dall'elenco tutti i prodotti non seguiti, con i loro limiti. Restano solo quelli con la stellina accesa. Le statistiche per prodotto restano."
|
|
Click="RemoveUnwatchedButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="ClearButton" Style="{StaticResource IconButton}"
|
|
Foreground="{DynamicResource Brush.Danger}"
|
|
ToolTip="Svuota l'elenco. Toglie tutti i prodotti e i loro limiti. Le statistiche per prodotto (aste concluse, prezzi tipici, consigli) restano: se il prodotto ricompare, i consigli ci sono ancora."
|
|
Click="ClearButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
<Button x:Name="ClearAllButton" Style="{StaticResource IconButton}"
|
|
Foreground="{DynamicResource Brush.Danger}"
|
|
ToolTip="Pulizia completa. Toglie tutti i prodotti, i loro limiti E le statistiche per prodotto. Lo storico delle aste non viene toccato: le statistiche si possono ricostruire da lì con «Pulisci dati incompleti» nello Storico."
|
|
Click="ClearAllButton_Click">
|
|
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
|
</Button>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ═══ Elenco prodotti: impostazioni e statistiche sulla stessa riga ═══ -->
|
|
<Grid Grid.Row="1" Margin="12">
|
|
<Border Background="{DynamicResource Brush.Surface}"
|
|
BorderBrush="{DynamicResource Brush.Border}" BorderThickness="1" CornerRadius="12">
|
|
<DataGrid x:Name="ProductsGrid" AutoGenerateColumns="False"
|
|
Background="Transparent" Margin="4"
|
|
CanUserAddRows="False" CanUserDeleteRows="False"
|
|
SelectionMode="Single" HeadersVisibility="Column"
|
|
RowHeight="32"
|
|
HorizontalScrollBarVisibility="Auto"
|
|
CellEditEnding="ProductsGrid_CellEditEnding"
|
|
SelectionChanged="ProductsGrid_SelectionChanged">
|
|
<DataGrid.Columns>
|
|
<!-- Stellina: acceso = le aste nuove entrano da sole -->
|
|
<DataGridTemplateColumn Header="" Width="Auto" MinWidth="38" IsReadOnly="True"
|
|
CanUserSort="False">
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate>
|
|
<Button Style="{StaticResource MiniIconButton}"
|
|
ToolTip="{Binding WatchTooltip}"
|
|
Command="{Binding DataContext.ProductWatchCommand,
|
|
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
|
CommandParameter="{Binding}">
|
|
<TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding WatchGlyph}">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.TextFaint}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsWatched}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Gold}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Button>
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
|
|
<!-- Auto, non *: con venti colonne accanto lo spazio residuo non basta mai
|
|
e i nomi lunghi restano tagliati. Cosi' la colonna prende la
|
|
larghezza del nome piu' lungo e la griglia scorre in orizzontale. -->
|
|
<DataGridTextColumn Header="Prodotto" Binding="{Binding DisplayName}"
|
|
Width="Auto" MinWidth="220" IsReadOnly="True"/>
|
|
|
|
<!-- ── Limiti propri del prodotto: modificabili ── -->
|
|
<DataGridTextColumn Header="Min €" Binding="{Binding MinPriceText}"
|
|
Width="Auto" MinWidth="74"
|
|
CellStyle="{StaticResource EditableCell}"
|
|
HeaderTemplate="{StaticResource EditableHeader}"
|
|
ElementStyle="{StaticResource EditableText}"/>
|
|
<DataGridTextColumn Header="Max €" Binding="{Binding MaxPriceText}"
|
|
Width="Auto" MinWidth="74"
|
|
CellStyle="{StaticResource EditableCell}"
|
|
HeaderTemplate="{StaticResource EditableHeader}"
|
|
ElementStyle="{StaticResource EditableText}"/>
|
|
<DataGridTextColumn Header="Puntate" Binding="{Binding MaxClicksText}"
|
|
Width="Auto" MinWidth="78"
|
|
CellStyle="{StaticResource EditableCell}"
|
|
HeaderTemplate="{StaticResource EditableHeader}"
|
|
ElementStyle="{StaticResource EditableText}"/>
|
|
<DataGridTextColumn Header="Valore reale €" Binding="{Binding MarketValueText}"
|
|
Width="Auto" MinWidth="96"
|
|
CellStyle="{StaticResource EditableCell}"
|
|
HeaderTemplate="{StaticResource EditableHeader}"
|
|
ElementStyle="{StaticResource EditableText}"/>
|
|
<DataGridTextColumn Header="Entro min" Binding="{Binding MaxStartMinutesText}"
|
|
Width="Auto" MinWidth="86"
|
|
CellStyle="{StaticResource EditableCell}"
|
|
HeaderTemplate="{StaticResource EditableHeader}"
|
|
ElementStyle="{StaticResource EditableText}"/>
|
|
|
|
<!-- Le colonne non stanno nell'albero visuale: un Binding qui non
|
|
erediterebbe alcun DataContext, quindi il valore è statico. -->
|
|
<DataGridComboBoxColumn Header="Stato" Width="Auto" MinWidth="112"
|
|
CellStyle="{StaticResource EditableCell}"
|
|
HeaderTemplate="{StaticResource EditableHeader}"
|
|
SelectedItemBinding="{Binding StateChoice}"
|
|
ItemsSource="{x:Static vm:ProductViewModel.StateChoices}"/>
|
|
|
|
<!-- ── Statistiche dello storico: sola lettura ── -->
|
|
<DataGridTextColumn Header="Aste" Binding="{Binding StatCountDisplay}"
|
|
Width="Auto" MinWidth="52" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
<DataGridTextColumn Header="Vinte" Binding="{Binding StatWonCount}"
|
|
Width="Auto" MinWidth="56" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
<DataGridTextColumn Header="%" Binding="{Binding StatWinRateDisplay}"
|
|
Width="Auto" MinWidth="52" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
<DataGridTextColumn Header="Media" Binding="{Binding StatAverageDisplay}"
|
|
Width="Auto" MinWidth="78" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
<DataGridTextColumn Header="Min" Binding="{Binding StatMinDisplay}"
|
|
Width="Auto" MinWidth="72" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
<DataGridTextColumn Header="Max" Binding="{Binding StatMaxDisplay}"
|
|
Width="Auto" MinWidth="72" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
|
|
<!-- ── Quanto vale, quanto costa vincerlo davvero ── -->
|
|
<DataGridTextColumn Header="Valore" Binding="{Binding StatValueDisplay}"
|
|
Width="Auto" MinWidth="80" IsReadOnly="True"
|
|
ElementStyle="{StaticResource ValueText}"/>
|
|
<DataGridTextColumn Header="Punt. vinc." Binding="{Binding StatWinnerBidsDisplay}"
|
|
Width="Auto" MinWidth="88" IsReadOnly="True"
|
|
ElementStyle="{StaticResource ValueText}"/>
|
|
<DataGridTextColumn Header="Costo reale" Binding="{Binding StatWinCostDisplay}"
|
|
Width="Auto" MinWidth="90" IsReadOnly="True"
|
|
ElementStyle="{StaticResource ValueText}"/>
|
|
<DataGridTextColumn Header="Risparmio" Binding="{Binding StatSavingsDisplay}"
|
|
Width="Auto" MinWidth="84" IsReadOnly="True"
|
|
ElementStyle="{StaticResource ValueText}"/>
|
|
|
|
<!-- ── La forbice, non solo il valore tipico ──
|
|
Su un articolo dove si vince con 12 puntate o con 900, la sola
|
|
mediana porta a impostare limiti che non reggono. -->
|
|
<DataGridTextColumn Header="Punt. min" Binding="{Binding StatMinWinnerBidsDisplay}"
|
|
Width="Auto" MinWidth="78" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="Punt. 75°" Binding="{Binding StatP75WinnerBidsDisplay}"
|
|
Width="Auto" MinWidth="78" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="Punt. max" Binding="{Binding StatMaxWinnerBidsDisplay}"
|
|
Width="Auto" MinWidth="80" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="Risp. min" Binding="{Binding StatMinSavingsDisplay}"
|
|
Width="Auto" MinWidth="80" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="Risp. max" Binding="{Binding StatMaxSavingsDisplay}"
|
|
Width="Auto" MinWidth="80" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="In utile" Binding="{Binding StatProfitableShareDisplay}"
|
|
Width="Auto" MinWidth="72" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="Ogni" Binding="{Binding StatFrequencyDisplay}"
|
|
Width="Auto" MinWidth="70" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<DataGridTextColumn Header="Verificate" Binding="{Binding StatWinnerBidsSampleDisplay}"
|
|
Width="Auto" MinWidth="82" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatsText}"/>
|
|
<!-- ── Limiti consigliati: sola lettura, più il bottone che li applica ── -->
|
|
<DataGridTextColumn Header="Min cons." Binding="{Binding SuggestedMinDisplay}"
|
|
Width="Auto" MinWidth="84" IsReadOnly="True"
|
|
ElementStyle="{StaticResource AdviceText}"/>
|
|
<DataGridTextColumn Header="Max cons." Binding="{Binding SuggestedMaxDisplay}"
|
|
Width="Auto" MinWidth="84" IsReadOnly="True"
|
|
ElementStyle="{StaticResource AdviceText}"/>
|
|
<DataGridTextColumn Header="Punt. cons." Binding="{Binding SuggestedMaxBidsDisplay}"
|
|
Width="Auto" MinWidth="88" IsReadOnly="True"
|
|
ElementStyle="{StaticResource AdviceText}"/>
|
|
|
|
<DataGridTemplateColumn Header="" Width="Auto" MinWidth="40" IsReadOnly="True" CanUserSort="False">
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate>
|
|
<!-- Applica i consigliati a questa riga soltanto. Il segno di
|
|
spunta si accende quando i limiti scritti sono già quelli
|
|
consigliati: serve a vedere a colpo d'occhio quali righe
|
|
resta da sistemare. -->
|
|
<Button Style="{StaticResource MiniIconButton}"
|
|
ToolTip="{Binding AdviceExplanation}"
|
|
Command="{Binding DataContext.ProductApplyAdviceCommand,
|
|
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
|
CommandParameter="{Binding}">
|
|
<TextBlock FontFamily="Segoe MDL2 Assets" Text="">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.TextFaint}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding HasAdvice}" Value="False">
|
|
<Setter Property="Opacity" Value="0.25"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding MatchesAdvice}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Success}"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding AdviceWarns}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Warning}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Button>
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
|
|
<DataGridTextColumn Header="Punt./asta" Binding="{Binding StatAverageBidsDisplay}"
|
|
Width="Auto" MinWidth="82" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
<DataGridTextColumn Header="Aggiunte" Binding="{Binding AutoAddedCountDisplay}"
|
|
Width="Auto" MinWidth="74" IsReadOnly="True"
|
|
ElementStyle="{StaticResource StatText}"/>
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
</Border>
|
|
|
|
<!-- Stato vuoto -->
|
|
<StackPanel x:Name="ProductsEmptyState" VerticalAlignment="Center" HorizontalAlignment="Center"
|
|
Visibility="Collapsed">
|
|
<TextBlock Style="{StaticResource Glyph}" Text="" FontSize="34"
|
|
Foreground="{DynamicResource Brush.TextFaint}"/>
|
|
<TextBlock Text="Nessun prodotto in elenco."
|
|
Margin="0,10,0,0" HorizontalAlignment="Center"
|
|
Foreground="{DynamicResource Brush.TextMuted}"/>
|
|
<TextBlock Text="Aggiungili dalla scheda Cerca: la stellina lo segue, l'ingranaggio lo mette qui per dargli dei limiti."
|
|
Margin="0,4,0,0" HorizontalAlignment="Center" TextWrapping="Wrap" MaxWidth="420"
|
|
TextAlignment="Center"
|
|
FontSize="{StaticResource Font.Size.Sm}"
|
|
Foreground="{DynamicResource Brush.TextFaint}"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Grid>
|
|
</UserControl>
|