マキャベリ的な質問があります(私にとって)。私の WPF アプリケーションには、ItemTemplate に Combobox を持つ ListBox があります。ユーザーが ComboBoxItem を選択すると、ListBox の ItemsSource である ObservableCollection に対していくつかの複雑な操作を行う必要があります。次に、変更されたデータで ListBox を表示する必要があります。問題は、ComboBox コントロールのイベント「SelectionChanged」を処理すると、イベントを処理するメソッドに入力するコンボボックス項目のソース クラスを変更するたびに、間違った結果が生成されることです。つまり、コードによって生成された SelectionChanged と、ユーザーがマウスで手動で生成した SelectionChanged を何らかの方法で区別する必要があります。私は多くの方法を試しましたが、うまくいきません:-(
私が最善だと思った解決策は、Combo の ItemContainerStyle の ContentPresenter のイベント「GotFocus」または「MouseUp」を処理するか、または ItemsPanel の同じイベント (「GotFocus」および「MouseUp」) を処理することです。コンボですが、私が処理したメソッドはイベントをキャプチャしませんでした(デバッグでは、カーソルはメソッドにまったく入りません)。
メソッドがすべて実行された後に ComboBoxItems のソースクラスの変更が発生するため、「最初のラウンド」が終了するまでブール値を使用してメソッド「SelectionChanged」を停止することはできません。
Combos のデフォルト値は常に最初であるとは限りません (簡単すぎるでしょう :-))、常に同じであるとは限りません。ユーザーがいずれかのコンボのアイテムを選択するたびに、他のコンボのデフォルト値を変更する必要があります。
手伝って頂けますか?ピレッジ
' 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