温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - ConvertBack is not called
c# visual-studio xaml converters

c# - 不调用ConvertBack

发布于 2020-03-31 23:15:05

我正在尝试编写一个通用控件,在其中可以通过INotifyPropertyChanged转换器传递不同的数据模型(所有实现)。数据可以毫无问题地传递到控件中,并可以正确显示(其中一些还使用IMultivalueConverts,可以正常工作)。尽管修改了数据,但IMultiValueConverter不调用MainControl的。

通用控件应仅显示根据ObservableCollection中的坐标计算出的矩形。

我将DebugConverters放在所有绑定上,除了ConvertBack之外,所有内容似乎都已更新。ListBox中的SourceUpdate也被调用。

我用不同的NotifyOn ... Updated,Mode和UpdateSourceTrigger尝试了此转换器,我总是看到控件中的值发生了变化,但从未看到主控件的ConvertBack。

使用了部分数据模板(更新正确完成),所有的DegreeTo ...转换器都被双向调用

        <DataTemplate x:Key="RectangleWithLabel">
            <Canvas IsHitTestVisible="True">
                <Rectangle x:Name="RectangleROI" MouseLeftButtonDown="myCanvas_PreviewMouseLeftButtonDown" >
                    <!--
                    <Rectangle.Visibility>
                        <Binding Path="ROI" Converter="{StaticResource NullToVisibilityConverter}"/>
                    </Rectangle.Visibility>
                    -->
                    <Canvas.Left>
                        <MultiBinding Converter="{StaticResource DegreeToScreenPixelConverterH}" Mode="TwoWay" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged" >
                            <Binding Path="ROI.Begin.PosH" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" />
                            <Binding Path="DataContext.UsedCoordinateSystem" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" NotifyOnSourceUpdated="True" Mode="TwoWay" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged" />
                        </MultiBinding>
                    </Canvas.Left>
                    <Canvas.Top>
                        <MultiBinding Converter="{StaticResource DegreeToScreenPixelConverterV}"  Mode="TwoWay" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged">
                            <Binding Path="ROI.Begin.PosV" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"   NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" />
                            <Binding Path="DataContext.UsedCoordinateSystem" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" NotifyOnSourceUpdated="True" Mode="TwoWay" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
                        </MultiBinding>
                    </Canvas.Top>
                    <Rectangle.Width>
                        <MultiBinding Converter="{StaticResource DegreeToScreenPixelWidthConverter}"  Mode="TwoWay" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged">
                            <Binding Path="ROI.Begin.PosH" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" />
                            <Binding Path="ROI.End.PosH" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"   NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" />
                            <Binding Path="DataContext.UsedCoordinateSystem" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" NotifyOnSourceUpdated="True" Mode="TwoWay" NotifyOnTargetUpdated="True"/>
                        </MultiBinding>
                    </Rectangle.Width>
                    <Rectangle.Height>
                        <MultiBinding Converter="{StaticResource DegreeToScreenPixelHeightConverter}"  Mode="TwoWay" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged">
                            <Binding Path="ROI.Begin.PosV" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"   NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True"/>
                            <Binding Path="ROI.End.PosV" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"   NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" />
                            <Binding Path="DataContext.UsedCoordinateSystem" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" NotifyOnSourceUpdated="True" Mode="TwoWay" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
                        </MultiBinding>
                    </Rectangle.Height>
                    <Rectangle.Fill>#33FF0000</Rectangle.Fill>
                    <Rectangle.Stroke>#FF00FF00</Rectangle.Stroke>
                    <Rectangle.IsHitTestVisible>true</Rectangle.IsHitTestVisible>
                </Rectangle>

包含所有数据的列表视图:

<ListView ItemsSource="{Binding Rectangles, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"   x:Name="listBox" Width="{Binding ActualWidth, ElementName=ImageControl, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" Height="{Binding ActualHeight, ElementName=ImageControl, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" ItemTemplate="{StaticResource RectangleWithLabel}" MouseMove="ListBox_MouseMove" DataContextChanged="ListBox_DataContextChanged" SourceUpdated="ListBox_SourceUpdated" IsSynchronizedWithCurrentItem="True" TargetUpdated="ListBox_TargetUpdated"  />

父级对ImageViewer的调用,此处是在前往ImageViewer的途中调用转换器,但从不调用ConvertBack:

        <common:ImageViewer x:Name="ctrlImage" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
            <common:ImageViewer.DataContext>
                <MultiBinding Converter="{StaticResource ConverterWhichIsOnlyCalledOneWay}" Mode="TwoWay" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged">
                    <Binding Path="." UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True"/>
                </MultiBinding>
            </common:ImageViewer.DataContext>
        </common:ImageViewer>

我该如何ConvertBack打电话?

编辑:

我对控件和转换器进行了概述。我想我错了,应该调用ConvertBack,即使没有大型转换器,一切都在更新。但是在向中添加一些元素时我仍然卡住了ObservableCollection当我添加一些值时,这些值会出现在MainWindow的DataContext中。但是转换器不会触发。当我将Observable.Countas绑定添加到Big Converter时,触发了更新,但是所有绑定都丢失了。

与原始代码相比,更改为:将所有内部变量更改为DependencyProperties,这使得更新对于中的单个条目可靠ObservableCollection

GUI和使用的转换器概述

查看更多

提问者
Joerch
被浏览
137
Joerch 2020-01-31 19:18

是时候自己回答问题了:

当假设两个元素之间存在直接连接时,变化会贯穿整个转换器时,我是错的。

因此,如果我在深层嵌套中有一个元素(只是将其视为一棵树的叶子),并且一次通过转换器(会更改其他一些对象)显示一次,并且在没有转换器的情况下同时显示一次,则该元素将在没有调用转换器。WPF非常聪明,可以看到值相同,并且不会通过转换器上下传递更改。