首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF区分编码-SelectionChanged和鼠标-SelectionChanged

WPF区分编码-SelectionChanged和鼠标-SelectionChanged
EN

Stack Overflow用户
提问于 2010-09-12 07:54:10
回答 1查看 1.5K关注 0票数 3

我有一个马基雅维利式的问题(对我来说)。在我的WPF应用程序中,我有一个在ItemTemplate中有一个组合框的ListBox。当用户选择一个ComboBoxItem时,我必须在作为ItemsSource的ListBox的ObservableCollection上执行一些复杂的操作,然后我必须使用更改后的数据显示ListBox。问题是,如果我处理ComboBox控件的事件"SelectionChanged“,每次修改我在处理该事件的方法中输入的comboboxItems的源类时,都会生成错误的结果。简而言之,我必须在某种程度上区分代码生成的SelectionChanged和用户使用鼠标手动生成的SelectionChanged。我试过很多方法,但都不管用:

我认为最好的方法是处理Combo的ItemContainerStyle的ContentPresenter的"GotFocus“或"MouseUp”事件,或者处理Combo的ItemsPanel的相同事件("GotFocus“和"MouseUp"),但我处理的方法没有捕获事件(在debug中,光标根本不会进入该方法)。

在“第一轮”完成之前,我不能使用布尔值来停止方法"SelectionChanged“,因为ComboBoxItems的源类的更改是在该方法全部执行之后发生的。

Combos的默认值并不总是第一个(这太容易了:-),并且不总是相同的。每次用户选择其中一个组合的项目时,其他组合的默认值都必须更改。

你能帮帮我吗?皮莱基

代码语言:javascript
复制
' 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-09-12 18:04:21

首先,我认为最好是在项目容器本身上处理事件,而不是在项目内的内容呈现器上。现在我想到了这一点,这可能就是为什么你看不到事件的原因。容器可能正在吞食事件以供选择。

但是无论哪种方式,如果你不能捕捉MouseDown/GotFocus事件,你可以使用PreviewMouseDown/PreviewGotFocus事件。如果您不确定这些意味着什么,您应该阅读有关wpf事件路由体系结构以及冒泡和隧道事件的信息。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3693168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档