gpt4 book ai didi

c# - 当 UnsetValue 中有一个转换值时,使用 convertback 的多重绑定(bind)不起作用

转载 作者:行者123 更新时间:2023-11-30 19:39:37 24 4
gpt4 key购买 nike

我有以下多重绑定(bind):

 <Grid.Visibility>
<MultiBinding Converter="{StaticResource MyMultiValueConverter}" Mode="TwoWay">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="MyVisibilityDependencyProperty" Mode="TwoWay"/>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="MyBoolProperty" Mode="TwoWay"/>
</MultiBinding>
</Grid.Visibility>

MyVisibilityDependencyProperty 是一个依赖属性。 MyBoolProperty 是一个普通属性。MyMultiValueConverter 的实现是重要的事情:

public class MyMultiValueConverter: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
//Not interesting
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new[] { value, Binding.DoNothing};
}
}

现在的场景:我做某事。这会触发对 ConvertBack-Method 的调用,这意味着我在那里遇到了一个断点。之后,我在 MyVisibilityDependencyProperty 的 OnPropertyChangedCallback 中遇到了一个断点。在那里我可以看到 MyVisibilityDependencyProperty 的新值是在 ConvertBack-Method 中设置的值。

现在是我不明白的问题。我将 ConvertBack-Method 的实现更改为:

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new[] { value, DependencyProperty.UnsetValue};
}

现在我遵循完全相同的场景。我做某事这会触发对 ConvertBack-Method 的调用,这意味着我在那里遇到了一个断点。在那之后什么也没有发生。不会调用 OnPropertyChangedCallback 并且不会更新 MyVisibilityDependencyProperty。为什么?

似乎如果数组中的值之一是 DependencyProperty.UnsetValue,所有值的传播都会停止。不仅针对该值,而且针对数组中的所有值。以下行为支持这一点:

return new[] { Binding.DoNothing, false };

这会调用 MyBoolProperty 的 setter 。

return new[] { DependencyProperty.UnsetValue, false };

这不会调用 MyBoolProperty 的 setter 。

我在文档中找不到任何解释的提示,我认为它没有意义。

最佳答案

I could not find any hints of explanation in documentation and it does not make sense in my opinion.

我不记得在文档中见过它,但您的观察是正确的:

如果 IMultiValueConverter.ConvertBack 结果中的任何 元素是UnsetValue,则整个建议值集被拒绝,即转换失败,并且所有子绑定(bind)都没有更新其源值。

相关代码可以在MultiBindingExpression类中找到。以下是节选。

internal override object ConvertProposedValue(object value)
{
object result;
bool success = ConvertProposedValueImpl(value, out result);
{
result = DependencyProperty.UnsetValue;
...
}
return result;
}

private bool ConvertProposedValueImpl(object value, out object result)
{
result = GetValuesForChildBindings(value);

object[] values = (object[])result;
int count = MutableBindingExpressions.Count;
bool success = true;

// use the smaller count
if (values.Length < count)
count = values.Length;

for (int i = 0; i < count; ++i)
{
value = values[i];
...
if (value == DependencyProperty.UnsetValue)
success = false; // if any element is UnsetValue, conversion fails
values[i] = value;
}

result = values;
return success;
}

至于有没有道理,我觉得有。结果数组中的 DoNothing 值表示应跳过相应的子绑定(bind),即不应更新其源值。这实际上提供了一种用于部分更新的机制。如果您考虑一下,我们唯一关心的场景是:

  1. 所有源更新成功
  2. 部分资源更新成功
  3. 完全失败:没有更新源

正常行为提供了(1),使用DoNothing可以满足(2)。可以说使用 UnsetValue 来指示完全失败是有意义的。这也符合其对单值转换器的含义:UnsetValue 表示转换失败。唯一的区别是 ConvertBack 返回 object[],所以你不能直接返回 UnsetValue。但是,您可以返回一个包含 UnsetValue 的数组:因为它的存在意味着整个结果都将被丢弃,所以数组长度实际上不必与子绑定(bind)。

关于c# - 当 UnsetValue 中有一个转换值时,使用 convertback 的多重绑定(bind)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27015105/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com