如何跳过更新MultiBinding
的某些子绑定?我已经在代码隐藏中定义了(我在XAML中遇到了一些麻烦,我觉得这并不重要 - 毕竟代码隐藏不是那么表达XAML)a MultiBinding
它有两个只读属性和一个生成单个值的普通属性。如果ConvertBack
,则不修改只读属性(它们维持其值)并且仅更改普通属性。
在定义MultiBinding
时,整个MultiBinding
设置为TwoWay
,但是设置适当的特定子绑定(前两个到OneWay
和第三个{{1} }})。
问题发生在我自己的控件中。然而,为了便于演示,我将其简化为较小的控件。此示例中显示的控件是一个类似TwoWay
的控件,允许选择[0.0; 1.0]范围。所选值由拇指表示,并显示为Slider
。
基本上,控件是由1行x 3列DependencyProperty
构建的,其中拇指位于中间列。要正确定位拇指,左列必须指定与所选位置对应的宽度。然而,这个宽度还取决于整个控件的实际宽度和拇指本身的实际宽度(这是因为位置是[0.0; 1.0]范围内的相对值)。
当拇指移动时,位置应该适当更新,但拇指宽度和控制宽度显然不会改变。
代码按预期工作,但是在拇指移动期间在IDE中运行时,当Grid
尝试将值设置为这两个只读属性时,输出窗口会混乱出现异常信息。我怀疑它没有害处,但有点烦人和误导。而且这意味着代码执行了其他操作,然后我希望它能够执行,因为我不想设置这些属性(这非常重要,以防它们不是只读的,这实际上会修改它们。)
MultiBinding
documentation提到允许单个子绑定覆盖MultiBinding
模式值,但它似乎不起作用。
也许这可以通过以某种方式表达对控件和拇指宽度(只读属性)的依赖性以某种方式解决。例如,单独注册其通知并在更改时强制执行更新。然而,这对我来说似乎并不自然。另一方面,MultiBinding
执行,因为所有左列宽度都取决于这三个属性。
以下是示例XAML代码。
MultiBinding
这是相应的代码隐藏
<UserControl x:Class="WpfTest.ExampleUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn" />
<ColumnDefinition x:Name="thumbColumn" Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- Rectangle used in the left column for better visualization. -->
<Rectangle Grid.Column="0">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- Thumb representing the Position property. -->
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" />
<!-- Rectangle used in the right column for better visualization. -->
<Rectangle Grid.Column="2">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</UserControl>
答案 0 :(得分:10)
最后我自己找到了解决方案。实际上它在documentation - 我不知道我是如何错过的,但我付出了沉重的代价(浪费时间)。
根据文档ConvertBack
应该返回Binding.DoNothing
关于没有设置值的位置(特别是需要OneWay
绑定)。另一个特殊值是DependencyProperty.UnsetValue
。
这不是一个完整的解决方案,因为现在IMultiValueConverter
实现必须知道返回特殊值的位置。但是我认为这个解决方案涵盖了大多数合理的案例。
答案 1 :(得分:4)
看起来MultiBinding无法正常工作。在我的练习之前,我已经看到了一些意想不到的行为(类似于你的行为)。你也可以在转换器中插入断点或一些跟踪,你可以找到一些有趣的事情,关于哪些转换器和何时被调用。 因此,如果可能,您应该避免使用MultiBinding。例如。您可以在视图模型中添加特殊属性,该属性将在其setter中设置mutable属性的值,并使用其getter中的所有三个属性返回所需的值。它类似于属性中的MultiValueConverter =)。
希望它有所帮助。