Creazione UserControl con Databinding
Quote from Alba on 24/09/2020, 12:27Salve a tutti e complimenti per il forum!
Sto scrivendo un'applicazione C# WPF per automatizzare il controllo di un dispositivo elettronico, fondamentalmente tramite una dll leggo lo stato del dispositivo che consiste in una stringa di 256 valori esadecimali a 8 bit. Questo stato rappresenta la programmazione "corrente" del dispositivo e deve essere visualizzata in maniera "User Friendly" tramite bottoni, combobox, checkbox ed altro.
A questo proposito ho scritto una serie di UserControls che ad oggi vengono aggiornati manualmente ogni volta che leggo lo stato del dispositivo, per semplicità:
- leggo la stringa di 256 valori
- per ogni valore della stringa, chiamo un metodo che mi aggiorna lo stato dello UserControl
- questo metodo, per esempio, cambia un testo o cambia il colore di un rettangolo
Mi piacerebbe molto automatizzare questo aggiornamento tramite DataBinding ma sto trovando qualche difficoltà nell'implementazione del codice. Ho letto l'ottimo post su
ma ancora credo mi manchi qualcosa, sopratutto per la gestione della sorgente dei dati.
Fatemi spiegare meglio con un esempio: supponiamo per semplicità che la stringa con lo stato del dispositivo sia composta da tre valori
string[] Dump = new string{"21", "20", "1A"};
il primo valore, Dump[0], vale 0x21 che tradotto in binario significa 00100001. Questo valore e' l'espressione dello stato di due UserControl diversi
CONTROLLO A | CONTROLLO B
0010000 | 1
dove
- CONTROLLO B e' un rettangolo che viene colorato di grigio se il valore e' 0 mentre di verde se il valore e' 1
- CONTROLLO A e' una textbox che deve riportare il restante del valore.
Il mio obiettivo sarebbe quello di ricevere la string[] Dump ed automaticamente aggiornare i controlli.
C'e' un modo semplice ed immediato per farlo?
Grazie a tutti
Salve a tutti e complimenti per il forum!
Sto scrivendo un'applicazione C# WPF per automatizzare il controllo di un dispositivo elettronico, fondamentalmente tramite una dll leggo lo stato del dispositivo che consiste in una stringa di 256 valori esadecimali a 8 bit. Questo stato rappresenta la programmazione "corrente" del dispositivo e deve essere visualizzata in maniera "User Friendly" tramite bottoni, combobox, checkbox ed altro.
A questo proposito ho scritto una serie di UserControls che ad oggi vengono aggiornati manualmente ogni volta che leggo lo stato del dispositivo, per semplicità:
- leggo la stringa di 256 valori
- per ogni valore della stringa, chiamo un metodo che mi aggiorna lo stato dello UserControl
- questo metodo, per esempio, cambia un testo o cambia il colore di un rettangolo
Mi piacerebbe molto automatizzare questo aggiornamento tramite DataBinding ma sto trovando qualche difficoltà nell'implementazione del codice. Ho letto l'ottimo post su
ma ancora credo mi manchi qualcosa, sopratutto per la gestione della sorgente dei dati.
Fatemi spiegare meglio con un esempio: supponiamo per semplicità che la stringa con lo stato del dispositivo sia composta da tre valori
string[] Dump = new string{"21", "20", "1A"};
il primo valore, Dump[0], vale 0x21 che tradotto in binario significa 00100001. Questo valore e' l'espressione dello stato di due UserControl diversi
CONTROLLO A | CONTROLLO B
0010000 | 1
dove
- CONTROLLO B e' un rettangolo che viene colorato di grigio se il valore e' 0 mentre di verde se il valore e' 1
- CONTROLLO A e' una textbox che deve riportare il restante del valore.
Il mio obiettivo sarebbe quello di ricevere la string[] Dump ed automaticamente aggiornare i controlli.
C'e' un modo semplice ed immediato per farlo?
Grazie a tutti
Quote from sabrina_c on 24/09/2020, 13:10Ciao Alba,
Se dovessi farlo io, farei la seguente cosa:
- Genero una classe "potabile" che contiene le property adatte a essere messe in binding, ad esempio, i 2 valori del Byte 0 che per te vale 21, sarebbero 2 property boolean : bool ControlloA{get;set;} e bool ControlloB{get;set} (le scrivo brevemente ma poi per farle funzionare in modo MVVM la classe ove le metto dovrebbe implementare l'interfaccia INotifyPropertyChanged e le property stesse, all'interno del loro metodo set dovrebbero scatenare l'evento.
- A questo punto, creo un converter da boolean a SolidColorBrush per restituire il Background color, e metto in Binding la property Background dello User Control con il mio Campo ControlloA, e uso il Converter per permettergli di settare il colore nel modo corretto.
In questo caso, non ti serve neppure la Dependency Property e se lo User Control non è complesso ma mostra solo una forma rettangolare puoi usare anche un oggetto Border a cui metti in Binding il Background con il tuo valore.
Se lo User Control è più complesso basta comunque il Binding per ottenere quel che ti serve.
Se non è chiaro sono a disposizione.
saluti
Ciao Alba,
Se dovessi farlo io, farei la seguente cosa:
- Genero una classe "potabile" che contiene le property adatte a essere messe in binding, ad esempio, i 2 valori del Byte 0 che per te vale 21, sarebbero 2 property boolean : bool ControlloA{get;set;} e bool ControlloB{get;set} (le scrivo brevemente ma poi per farle funzionare in modo MVVM la classe ove le metto dovrebbe implementare l'interfaccia INotifyPropertyChanged e le property stesse, all'interno del loro metodo set dovrebbero scatenare l'evento.
- A questo punto, creo un converter da boolean a SolidColorBrush per restituire il Background color, e metto in Binding la property Background dello User Control con il mio Campo ControlloA, e uso il Converter per permettergli di settare il colore nel modo corretto.
In questo caso, non ti serve neppure la Dependency Property e se lo User Control non è complesso ma mostra solo una forma rettangolare puoi usare anche un oggetto Border a cui metti in Binding il Background con il tuo valore.
Se lo User Control è più complesso basta comunque il Binding per ottenere quel che ti serve.
Se non è chiaro sono a disposizione.
saluti
Quote from Miky on 24/09/2020, 19:40Questo potrebbe aiutarti.
E' la base e quindi migliorabile, anche usando un Converter come suggerito da Sabrina
Code Behind
public partial class MainWindow : Window
{public Dump dump { get; set; }
public MainWindow()
{
InitializeComponent();
dump = new Dump();
dump.D0 = "0010000";
dump.D1 = "1";
this.DataContext = dump;
}public class Dump : INotifyPropertyChanged
{
private string d0;
public string D0
{
get
{
return d0;
}
set
{
if (d0 == value) return;
d0 = value;
NotifyPropertyChanged();
}
}private string d1;
public string D1
{
get
{
return d1;
}
set
{
if (d1 == value) return;
d1 = value;if (value == "1")
{
Color = Brushes.Gray;
}
else
{
Color = Brushes.Green;
}
NotifyPropertyChanged();
}
}private SolidColorBrush color;
public SolidColorBrush Color
{
get
{
return color;
}
set
{
if (color == value) return;
color = value;
NotifyPropertyChanged();
}
}#region NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}}
XAML
<Grid>
<StackPanel Margin="0,100,0,0">
<TextBox Text="{Binding D0}" Height="20" Width="100" />
<TextBox Text="{Binding D1}" Height="20" Width="100" />
<Rectangle Fill="{Binding Color}" Height="20" Width="100" />
</StackPanel></Grid>
Copia/incolla e dovrebbe funzionare 🙂
Questo potrebbe aiutarti.
E' la base e quindi migliorabile, anche usando un Converter come suggerito da Sabrina
Code Behind
public partial class MainWindow : Window
{public Dump dump { get; set; }
public MainWindow()
{
InitializeComponent();
dump = new Dump();
dump.D0 = "0010000";
dump.D1 = "1";
this.DataContext = dump;
}public class Dump : INotifyPropertyChanged
{
private string d0;
public string D0
{
get
{
return d0;
}
set
{
if (d0 == value) return;
d0 = value;
NotifyPropertyChanged();
}
}private string d1;
public string D1
{
get
{
return d1;
}
set
{
if (d1 == value) return;
d1 = value;if (value == "1")
{
Color = Brushes.Gray;
}
else
{
Color = Brushes.Green;
}
NotifyPropertyChanged();
}
}private SolidColorBrush color;
public SolidColorBrush Color
{
get
{
return color;
}
set
{
if (color == value) return;
color = value;
NotifyPropertyChanged();
}
}#region NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}}
XAML
<Grid>
<StackPanel Margin="0,100,0,0">
<TextBox Text="{Binding D0}" Height="20" Width="100" />
<TextBox Text="{Binding D1}" Height="20" Width="100" />
<Rectangle Fill="{Binding Color}" Height="20" Width="100" />
</StackPanel></Grid>
Copia/incolla e dovrebbe funzionare 🙂