I have a machiavellian question (for me). In my WPF application I have a ListBox that has in the ItemTemplate a Combobox. When the user select a ComboBoxItem, I have to do some complex operations on the ObservableCollection that is the ItemsSource of the ListBox, then I have to show the ListBox with the changed data. The problem is that if I handle the event "SelectionChanged" of the ComboBox control, every time I modify the source-class of the comboboxItems I enter in the method that handle the event, and this generate wrong results. In short I have to distinguish, in some way, between the SelectionChanged generated by code, and the SelectionChanged generated manually by the user with the mouse. I have tried many ways, but nothing that works :-(
The soution I thought was the best, is to handle the event "GotFocus" or "MouseUp" of the ContentPresenter of the ItemContainerStyle of the Combo, or else to handle the same events ("GotFocus" and "MouseUp") of the ItemsPanel of the Combo, but the method I handled didn't capture the event (in debug the cursor doesn't enter at all in the method).
I can't use a boolean to stop the method "SelectionChanged" until the "first round" is finished, because the changes of the source-class of the ComboBoxItems occurs after that the method has been all executed.
The default value of the Combos is not always the first (it would be too easy :-)), and not always the same. Everytime the user select an item of one of the Combo, the default value of the other Combos has to change.
Can you help me? Pileggi
' XAML
<Style x:Key="modComboCriteriEventParts" TargetType="{x:Type ComboBox}">
<EventSetter Event="Selector.SelectionChanged" Handler="cb_SelectionChanged"/>
</Style>
<DataTemplate x:Key="modLBoxCriteriParts">
<ComboBox Style = "{StaticResource modComboCriteriEventParts}"
ItemsSource = "{Binding CriteriItemList}"
ItemContainerStyle = "{DynamicResource modComboContainerParts}"
SelectedIndex = "{Binding valueSelected}" ... />
</DataTemplate>
<ListBox x:Name="lbCriteri" IsSynchronizedWithCurrentItem="True"
ItemsSource = "{Binding CriteriList, Source={StaticResource P_CriteriDataSource}}"
ItemTemplate = "{DynamicResource modLBoxCriteriParts}"
... />
' Code Behind
Private Sub cb_SelectionChanged(ByVal sender As System.Object, ByVal e As SelectionChangedEventArgs)
Dim ri as New RicambiCriteriList() As ObservableCollection(Of P_CriteriItem)
' some complex operations with ri ...
be = BindingOperations.GetBindingExpression(Me.lbCriteri, ListBox.ItemsSourceProperty)
Dim allCriteri As P_Criteri = DirectCast(be.DataItem, P_Criteri)
allCriteri.AddData (ri)
e.Handled = True
End Sub
' Source-Class
Public Class P_Criteri
Private _CriteriList As New ObservableCollection(Of P_CriteriItem)
Public ReadOnly Property CriteriList() As ObservableCollection(Of P_CriteriItem)
Get
CriteriList = _CriteriList
End Get
End Property
Public Sub AddData(ByVal CriteriListPass As ObservableCollection(Of P_CriteriItem))
_CriteriList.Clear()
For Each a As P_CriteriItem In CriteriListPass
_CriteriList.Add(a)
Next
End Sub
End Class
Public Class P_CriteriItem
Implements INotifyPropertyChanged
Public Sub New(ByVal criterioPass As String, ByVal CriteriItemListPass As ObservableCollection(Of P_CriteriItemValore), _
ByVal widthCriteriValuesPass As Double)
Me._criterio = criterioPass
Me._CriteriItemList = CriteriItemListPass
Me._widthCriteriValues = widthCriteriValuesPass
End Sub
Private _criterio As String = ""
Private _CriteriItemList As New ObservableCollection(Of P_CriteriItemValore)
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Property criterio() As String
Get
Return Me._criterio
End Get
Set(ByVal value As String)
If Not Object.Equals(Me._criterio, value) Then
Me._criterio = value
Me.OnPropertyChanged ("criterio")
End If
End Set
End Property
Public Property CriteriItemList() As ObservableCollection(Of P_CriteriItemValore)
Get
Return Me._CriteriItemList
End Get
Set(ByVal value As ObservableCollection(Of P_CriteriItemValore))
If Not Object.Equals(Me._CriteriItemList, value) Then
Me._CriteriItemList = value
Me.OnPropertyChanged ("CriteriItemList")
End If
End Set
End Property
Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
Dim handler As PropertyChangedEventHandler = Me.PropertyChangedEvent
If handler IsNot Nothing Then
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class
Public Class P_CriteriItemValore
Implements INotifyPropertyChanged
Public Sub New(ByVal criterioValorePass As String)
Me._criterioValore = criterioValorePass
End Sub
Private _criterioValore As String = Nothing
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Property criterioValore() As String
Get
Return Me._criterioValore
End Get
Set(ByVal value As String)
If Not Object.Equals(Me._criterioValore, value) Then
Me._criterioValore = value
Me.OnPropertyChanged ("criterioValore")
End If
End Set
End Property
Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
Dim handler As PropertyChangedEventHandler = Me.PropertyChangedEvent
If handler IsNot Nothing Then
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class