Was bei ASP.NET sehr einfach war, ist bei Silverlight mit großen Mühen verbunden. Zwar unterstützt das Silverlight Datagrid eine Mehrfachauswahl per Attribut, aber die Listbox nicht. Ich zeige im folgenden Beispiel wie man mit Checkboxen dem Benutzer die Auswahl erlauben kann. Anschliessend sollen diese Checkboxen durchlaufen werden.
Hört sich einfach an, ist es aber nicht, da der Inhalt des Datatemplates nicht angesprochen werden kann. Auch Tricks per Findname oder x:Namer funtkionieren nicht. Eine unschöne Möglichkeit ist, mit Hilfe des visualtreehelpers komplett die Seite zu durchlaufen. Das ist sehr unhandlich da eine checkbox schon mindestens aus zwei Controls besteht, einem Textblock und einem Rectangle.
Meine Lösung verwendet zwei-Wege Datenbindung. Zuerst kommt der mühsame Teil eine Klasse zu schreiben. Diese muss für die Checkbox ein zusätzliches Property aufweisen und das Interface für die Zwei Wege Bindung implementieren.
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Public Class Listboxdaten
Implements INotifyPropertyChanged
Private _checked As Boolean
Public Property checked() As Boolean
Get
Return _checked
End Get
Set(ByVal value As Boolean)
_checked = value
OnPropertyChanged("checked")
End Set
End Property
Private _daten As String
Public Property daten() As String
Get
Return _daten
End Get
Set(ByVal value As String)
_daten = value
OnPropertyChanged("daten")
End Set
End Property
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(ByVal name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub
End Class
Dann noch XAML und die zwei Wege Datenbindung in der Checkbox. Mit der Binding Syntax müssten Sie sich auskennen.
<ListBox x:Name="lstFields" SelectionChanged="lstFields_SelectionChanged" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" x:Name="stack1">
<CheckBox x:Name="chkFields" IsChecked="{Binding checked, Mode=TwoWay}"></CheckBox>
<TextBlock Text="{Binding daten}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="Button1" Width="30" Height="20" Click="Button1_Click"></Button>
Im Loaded Event werden dann die Einträge in der Listbox vom passenden Typ erzeugt
Private Sub page17_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
lstFields.Items.Add(New Listboxdaten With {.checked = True, .daten = "eins"})
lstFields.Items.Add(New Listboxdaten With {.checked = True, .daten = "zwei"})
lstFields.Items.Add(New Listboxdaten With {.checked = True, .daten = "drei"})
Im Button Click Handler kann dann auf das ListboxItem zugegriffen werden und nach einem Typ Cast die checked Eigenschaft gelesen werden.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
For Each i In lstFields.Items
If CType(i, Listboxdaten).checked Then
MessageBox.Show("checked")
End If
Next
End Sub
Natürlich gibts auch andere Lösungen zb mit einer ObservableCollection. Aber einfacher geht es meiner Ansicht nach nicht mehr.