Binding en code C#22 avril 2010

Le Binding WPF en XAML est une écriture plutôt pratique qui permet, par exemple, de lier une ListBox à une collection d’objets, ou une propriété string à une TextBox pour en afficher le contenu.
Cette écriture a un équivalent en C#, qui vous permet de définir du Binding dynamique dans votre code.
Binding XAML
Pour vous présenter l’équivalence écriture XAML / écriture C#, je vais utiliser un exemple simple avec une TextBox bindée sur une propriété du ViewModel défini comme DataContext de la fenêtre.
ViewModel
class ViewModel : DependencyObject
{
public string SampleText
{
get { return (string)GetValue(SampleTextProperty); }
set { SetValue(SampleTextProperty, value); }
}
public static readonly DependencyProperty SampleTextProperty =
DependencyProperty.Register("SampleText", typeof(string),
typeof(ViewModel), new UIPropertyMetadata("Bonjour le monde !"));
}
XAML
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1">
<Window.DataContext>
<my:ViewModel />
</Window.DataContext>
<Grid>
<TextBox Text="{Binding SampleText}" />
</Grid>
</Window>
Binding en code C#
Dans la partie XAML, plus besoin donc d’écrire l’expression de Binding sur la propriété Text, il suffit juste de nommer le contrôle:
<TextBox Name="MyBox" />
Utilisant le même ViewModel que l’exemple précédent, nous pouvons écrire ce code au niveau du constructeur de notre fenêtre:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Binding bText = new Binding();
bText.Path = new PropertyPath("SampleText");
bText.Source = this.DataContext; // ou new ViewModel()
MyBox.SetBinding(TextBox.TextProperty, bText);
}
}
Lien MegaSnippets.com : WPF Binding in C#
Il y a d’autres propriétés de Binding comme le Mode (OneWay, TwoWay,…) et l’UpdateSourceTrigger qui peuvent être définies sur l’objet Binding (ici bText).
L’avantage de cette façon de faire est qu’il devient alors possible de spécifier un Binding de manière dynamique. Par exemple, vous pouvez vous Binder sur un élément spécifique d’un tableau en définissant l’indexeur de cette manière :
int i = 5;
bText.Path = new PropertyPath(string.Format("SampleArray[{0}]", i));
Bonjour Grégory,
Je suis confronté à un problème : Je dois afficher 4000 places très rapidement, avec beaucoup de fonctions graphiques. Je teste alors avec un DataGrid en WPF. Chaque colonne est alors indexée. Donc, il faut un paramètre au binding. Quand je ne passe pas de paramètre, ça fonctionne, mais dès que j’ai un paramètre, le chargement me renvoie l’erreur suivante :
System.Windows.Data Error: 17 : Cannot get ‘ItemToString’ value (type ‘String’) from » (type ‘ObservableCollectionLignePlaces’). BindingExpression:Path=ItemToString[104]; DataItem=’ObservableCollectionLignePlaces’ (HashCode=30840839); target element is ‘TextBlock’ (Name= »); target property is ‘Text’ (type ‘String’) TargetParameterCountException:’System.Reflection.TargetParameterCountException: Nombre de paramètres incorrects.
Voici mon code :
Dim tbl As New ObservableCollectionLignesPlaces
Dim k = 0
For j = 0 To 19
Dim row = New ObservableCollectionLignePlaces
For i = 0 To 149
k += 1
Dim place = New Place With {.ID = k}
row.Add(place)
Next
tbl.Add(row)
Next
For i = 0 To 149
Dim bind = New System.Windows.Data.Binding
bind.Path = New PropertyPath(« ItemToString[" & i & "]« )
Dim col = New System.Windows.Controls.DataGridTextColumn() With {.Binding = bind}
WindowControlDessinPanel1.DataGrid1.Columns.Add(col)
Next
WindowControlDessinPanel1.DataGrid1.ItemsSource = tbl
Et pour les données :
Public Class ObservableCollectionLignesPlaces
Inherits Collections.ObjectModel.ObservableCollection(Of ObservableCollectionLignePlaces)
End Class
Public Class ObservableCollectionLignePlaces
Inherits Collections.ObjectModel.ObservableCollection(Of Place)
Default Public ReadOnly Property ItemToString(ByVal Index As Integer) As String
Get
Return Item(Index).ToString
End Get
End Property
End Class
Public Class Place
Public ID As Integer
Public Overrides Function ToString() As String
Return CStr(ID)
End Function
End Class
Je ne vois pas que tu ais précisé la source pour ton Binding. (bind.Source = )
Très sympa comme blog, vraiment de chouettes articles. Et un gros +1 pour le thème du blog que je trouve très élégant et clair. Bravo :)
Merci beaucoup de votre intérêt pour mon blog et pour le skin ;)