Wpf IValueConverter仅在第一次显示数据绑定树视图时调用

Wpf IValueConverter仅在第一次显示数据绑定树视图时调用,wpf,treeview,datatemplate,ivalueconverter,Wpf,Treeview,Datatemplate,Ivalueconverter,我有一个绑定到ObservableCollection(正确实现IPropertyNotifyChanged)的树视图。每个TreeViewItem都是一个HierarchycalDataTemplate。我在文本块上有一个绑定到“amount”的转换器,如果字符串表示负数,它会将前景色更改为红色。第一次加载TreeView时,所有金额都正确显示。但是,如果基础的可观察收集发生变化,则数量会正确变化,但颜色不会发生变化(即负“数量”显示为白色而不是红色) 我已尝试使用IValueConverte

我有一个绑定到ObservableCollection(正确实现IPropertyNotifyChanged)的树视图。每个TreeViewItem都是一个HierarchycalDataTemplate。我在文本块上有一个绑定到“amount”的转换器,如果字符串表示负数,它会将前景色更改为红色。第一次加载TreeView时,所有金额都正确显示。但是,如果基础的可观察收集发生变化,则数量会正确变化,但颜色不会发生变化(即负“数量”显示为白色而不是红色)

我已尝试使用IValueConverter和IMultiValueConverter。我已确保所有内容都与UpdateSourceTrigger=PropertyChanged绑定。转换器没有被调用

每次“金额”改变时,我需要做什么才能调用转换器

谢谢 安迪

模板:

<!-- Data templates-->
    <HierarchicalDataTemplate x:Key="RealTemplate" DataType="{x:Type l:Account}" ItemsSource="{Binding Path=children}">
        <DockPanel LastChildFill="True">
            <TextBlock x:Name="AccountTitle" Text="{Binding Path=title}" Foreground="White" DockPanel.Dock="Left"/>
            <TextBox x:Name="EditAccountTitle" Text="{Binding Path=title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource RoundedTextBox}" FontWeight="Bold" LostFocus="tvLostFocus" PreviewKeyDown="tvKeyDown" LostKeyboardFocus="tvLostFocus" Visibility="Collapsed" DockPanel.Dock="Left" l:FocusExtension.IsFocused="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" CaretIndex="{x:Static sys:Int32.MaxValue}"/>
            <TextBlock Text="{Binding Path=amount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Right" TextAlignment="Right">
                <TextBlock.Foreground>
                    <MultiBinding Converter="{StaticResource GetColourConverterAmountM}" UpdateSourceTrigger="PropertyChanged">
                        <Binding/>
                    </MultiBinding>
                </TextBlock.Foreground>
            </TextBlock>
        </DockPanel>            
        <HierarchicalDataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=isEditable}" Value="True">
                <Setter TargetName="AccountTitle" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="EditAccountTitle" Property="Visibility" Value="Visible"/>                                        
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=isEditable}" Value="False">
                <Setter TargetName="AccountTitle" Property="Visibility" Value="Visible"/>
                <Setter TargetName="EditAccountTitle" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource TreeViewTopItemConverter}}" Value="False">
                <DataTrigger.Setters>
                    <Setter Property="ContextMenu" Value="{StaticResource RealAccountMenu}"/>
                </DataTrigger.Setters>
            </DataTrigger>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource TreeViewTopItemConverter}}" Value="True">
                <DataTrigger.Setters>
                    <Setter Property="ContextMenu" Value="{StaticResource CategoryMenu}"/>
                </DataTrigger.Setters>
            </DataTrigger>
        </HierarchicalDataTemplate.Triggers>
    </HierarchicalDataTemplate>
可观察收集:

Public Class Account
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged()
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Nothing))
End Sub

Private _name, _title, _amount, _target As String
Private _ID, _type, _category, _column As Integer
Private _isEditable, _isNodeExpanded, _isNodeSelected As Boolean
Private _children As ObservableCollection(Of Account)

Public Sub New(__ID As Integer, __name As String, __title As String, __amount As String, __target As String, __type As Integer, __category As Integer, __column As Integer)
    children = New ObservableCollection(Of Account)
    _ID = __ID
    _name = __name
    _title = __title
    _amount = __amount
    _target = __target
    _category = __category
    _type = __type
    _column = __column
    _isEditable = False
    _isNodeExpanded = True
    _isNodeSelected = False
End Sub

Property ID As Integer
    Get
        Return _ID
    End Get
    Set(value As Integer)
        _ID = value
        NotifyPropertyChanged()
    End Set
End Property

Property name As String
    Get
        Return _name
    End Get
    Set(value As String)
        _name = value
        NotifyPropertyChanged()
    End Set
End Property

Property title As String
    Get
        Return _title
    End Get
    Set(value As String)
        _title = value
        NotifyPropertyChanged()
    End Set
End Property

Property amount As String
    Get
        Return _amount
    End Get
    Set(value As String)
        _amount = value
        NotifyPropertyChanged()
    End Set
End Property

Property target As String
    Get
        Return _target
    End Get
    Set(value As String)
        _target = value
        NotifyPropertyChanged()
    End Set
End Property

Property category As Integer
    Get
        Return _category
    End Get
    Set(value As Integer)
        _category = value
        NotifyPropertyChanged()
    End Set
End Property

Property type As Integer
    Get
        Return _type
    End Get
    Set(value As Integer)
        _type = value
        NotifyPropertyChanged()
    End Set
End Property

Property column As Integer
    Get
        Return _column
    End Get
    Set(value As Integer)
        _column = value
        NotifyPropertyChanged()
    End Set
End Property

Property isEditable As Boolean
    Get
        Return _isEditable
    End Get
    Set(value As Boolean)
        _isEditable = value
        NotifyPropertyChanged()
    End Set
End Property

Property isNodeExpanded As Boolean
    Get
        Return _isNodeExpanded
    End Get
    Set(value As Boolean)
        _isNodeExpanded = value
        NotifyPropertyChanged()
    End Set
End Property

Property isNodeSelected As Boolean
    Get
        Return _isNodeSelected
    End Get
    Set(value As Boolean)
        _isNodeSelected = value
        NotifyPropertyChanged()
    End Set
End Property

Property children As ObservableCollection(Of Account)
    Get
        Return _children
    End Get
    Set(value As ObservableCollection(Of Account))
        _children = value
        NotifyPropertyChanged()
    End Set
End Property
End Class

您需要将TextBlock的前景属性绑定到
amount
,并使用转换器将
amount
转换为颜色。当
金额
值更改时,前台将更新。例如(不使用多重绑定):


同样
getcolorconverteramount
应该实现
IValueConverter
而不是
IMultiValueConverter
@RohitVats是的。这就是为什么在我的回答中从
getcolorconverteramountm
中删除了'M',假设OP在实现
IValueConverter
时没有'M'。很公平+1答案:)wooow感谢这些(让OP清楚地使用
IValueConverter
,当然还有upvote):)太棒了。谢谢工作完美。
Public Class Account
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged()
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Nothing))
End Sub

Private _name, _title, _amount, _target As String
Private _ID, _type, _category, _column As Integer
Private _isEditable, _isNodeExpanded, _isNodeSelected As Boolean
Private _children As ObservableCollection(Of Account)

Public Sub New(__ID As Integer, __name As String, __title As String, __amount As String, __target As String, __type As Integer, __category As Integer, __column As Integer)
    children = New ObservableCollection(Of Account)
    _ID = __ID
    _name = __name
    _title = __title
    _amount = __amount
    _target = __target
    _category = __category
    _type = __type
    _column = __column
    _isEditable = False
    _isNodeExpanded = True
    _isNodeSelected = False
End Sub

Property ID As Integer
    Get
        Return _ID
    End Get
    Set(value As Integer)
        _ID = value
        NotifyPropertyChanged()
    End Set
End Property

Property name As String
    Get
        Return _name
    End Get
    Set(value As String)
        _name = value
        NotifyPropertyChanged()
    End Set
End Property

Property title As String
    Get
        Return _title
    End Get
    Set(value As String)
        _title = value
        NotifyPropertyChanged()
    End Set
End Property

Property amount As String
    Get
        Return _amount
    End Get
    Set(value As String)
        _amount = value
        NotifyPropertyChanged()
    End Set
End Property

Property target As String
    Get
        Return _target
    End Get
    Set(value As String)
        _target = value
        NotifyPropertyChanged()
    End Set
End Property

Property category As Integer
    Get
        Return _category
    End Get
    Set(value As Integer)
        _category = value
        NotifyPropertyChanged()
    End Set
End Property

Property type As Integer
    Get
        Return _type
    End Get
    Set(value As Integer)
        _type = value
        NotifyPropertyChanged()
    End Set
End Property

Property column As Integer
    Get
        Return _column
    End Get
    Set(value As Integer)
        _column = value
        NotifyPropertyChanged()
    End Set
End Property

Property isEditable As Boolean
    Get
        Return _isEditable
    End Get
    Set(value As Boolean)
        _isEditable = value
        NotifyPropertyChanged()
    End Set
End Property

Property isNodeExpanded As Boolean
    Get
        Return _isNodeExpanded
    End Get
    Set(value As Boolean)
        _isNodeExpanded = value
        NotifyPropertyChanged()
    End Set
End Property

Property isNodeSelected As Boolean
    Get
        Return _isNodeSelected
    End Get
    Set(value As Boolean)
        _isNodeSelected = value
        NotifyPropertyChanged()
    End Set
End Property

Property children As ObservableCollection(Of Account)
    Get
        Return _children
    End Get
    Set(value As ObservableCollection(Of Account))
        _children = value
        NotifyPropertyChanged()
    End Set
End Property
End Class
<TextBlock Text="{Binding Path=amount, Mode=TwoWay}"
           Foreground="{Binding Path=amount,
                           Converter="{StaticResource GetColourConverterAmount}" 
           DockPanel.Dock="Right" TextAlignment="Right">