wpf 处理 MultiBinding 中绑定的 bool 回退值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14226638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Handling a bool fallback value for a binding within a MultiBinding
提问by justin peterson
I have a MultiBindingconverter that determines the visibility of a control depending on if both of my Binding fields evaluate to true. If for some reason it can't reach either of these bool properties, I want to set them to evaluate to true. For example:
我有一个MultiBinding转换器,它根据我的两个绑定字段是否评估为真来确定控件的可见性。如果由于某种原因它无法达到这些 bool 属性中的任何一个,我想将它们设置为评估为真。例如:
The code that I currently have is:
我目前拥有的代码是:
<MultiBinding Converter="{StaticResource AndToVisibilityConverter1}" FallbackValue="Visible">
<Binding Path="IsConnected" FallbackValue="true" />
<Binding Path="CurrentUser.IsConsumerOnlyAgent" Converter="{StaticResource InvertedBooleanConverter1}" FallbackValue="True" />
</MultiBinding>
The code runs fine, however I get the error message in my IDE's output that indicates:
代码运行良好,但是我在 IDE 的输出中收到错误消息,指出:
System.Windows.Data Error: 11 : Fallback value 'True' (type 'String') cannot be converted for use in 'Visibility' (type 'Visibility'). BindingExpression:Path=IsConnected; DataItem=null; target element is 'StackPanel' (Name='');
Which I've pinpointed to this converter and verified it is where the XAML error is. Sorry for the ignorance here, but is there a way to possibly set the FallbackValue to each of these bindings to evaluate to "true" upon failure to obtain the set path? Thanks in advance
我已经确定了这个转换器并验证了它是 XAML 错误所在。很抱歉这里的无知,但是有没有办法可能将 FallbackValue 设置为这些绑定中的每一个,以便在无法获取设置路径时评估为“true”?提前致谢
Update:
更新:
Here's the code for my Visibility Converter (I use this in several places throughout my app, just want to add fallback values):
这是我的 Visibility Converter 的代码(我在整个应用程序的几个地方使用它,只是想添加回退值):
internal class AndToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return Visibility.Collapsed;
foreach (var value in values)
{
if (value == null || !(value is bool))
return Visibility.Collapsed;
if (!((bool) value))
return Visibility.Collapsed;
}
return Visibility.Visible;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
回答by Metro Smurf
The FallbackValuevalue should be the Visibilityvalue to fallback on when the binding fails:
该FallbackValue值应该是Visibility值绑定失败时回退上:
<Binding Path="CurrentUser.IsConsumerOnlyAgent"
Converter="{StaticResource InvertedBooleanConverter1}"
FallbackValue="Visible" />
EDIT
编辑
From the FallbackValue documentation:
fallbackValue
An attribute or object element value of the same type as the target property. See that type's documentation for XAML usage information. That type may or may not support attribute syntax for its values, or may or may not support object element syntax (which requires a default constructor on that type). The target property type will therefore influence which syntax you use for the value of the FallbackValue property.
fallbackValue
与目标属性类型相同的属性或对象元素值。有关 XAML 使用信息,请参阅该类型的文档。该类型可能支持也可能不支持其值的属性语法,或者可能支持也可能不支持对象元素语法(这需要该类型的默认构造函数)。因此,目标属性类型将影响您用于 FallbackValue 属性值的语法。
In this case, the target property of the MultiBinding is the Visibility property. Even though the value of the child MultiBinding properties is expecting a bool, the parent MultiBinding is expecting a Visiblity value from the binding. This means the FallbackValue for each of the MultiBinding properties should have a FallbackValue for the Visibility property.
在这种情况下,MultiBinding 的目标属性是 Visibility 属性。即使子 MultiBinding 属性的值需要 bool,父 MultiBinding 也需要来自绑定的 Visiblity 值。这意味着每个 MultiBinding 属性的 FallbackValue 应该具有 Visibility 属性的 FallbackValue。
Seems a bit counter-intuitive, but does make sense when thought through (IMO), re: if there was not a converter on the MultiBindng, then the return values of the binding should be a Visibility value. Remove the converter from the equation and it may help to clear things up.
似乎有点违反直觉,但经过深思熟虑后确实有意义(IMO),re:如果 MultiBindng 上没有转换器,则绑定的返回值应该是 Visibility 值。从等式中删除转换器,它可能有助于澄清问题。
For your case, skip the FallbackValue for each of the MultiBinding values and set the FallbackValue on the MultiBinding as you have now.
对于您的情况,跳过每个 MultiBinding 值的 FallbackValue 并像现在一样在 MultiBinding 上设置 FallbackValue。
<MultiBinding Converter="{StaticResource AndToVisibilityConverter1}" FallbackValue="Visible">
<Binding Path="IsConnected" />
<Binding Path="CurrentUser.IsConsumerOnlyAgent" Converter="{StaticResource InvertedBooleanConverter1}" />
</MultiBinding>
回答by bj0
After some testing, it seems that when a "child binding" in a MultiBinding fails (due to UnsetValue or failure to find bound property) the child binding's FallbackValues get passed into the Converter on the MultiBinding.
经过一些测试,似乎当 MultiBinding 中的“子绑定”失败(由于 UnsetValue 或找不到绑定属性)时,子绑定的 FallbackValues 会传递到 MultiBinding 上的 Converter 中。
The odd part is that the type of the FallbackValue on the child bindingis required to match the target of the MultiBinding. I don't understand this requirement, as the MultiBinding converter can take values from bindings that don't match that type.
奇怪的是,子绑定上的 FallbackValue 的类型需要匹配MultiBinding的目标。我不明白这个要求,因为 MultiBinding 转换器可以从与该类型不匹配的绑定中获取值。
With this in mind, the easiest workaround is to modify your MultiBinding's Converter to handle multiple types. In this case, it would need to handle boolean and Visibility.
考虑到这一点,最简单的解决方法是修改 MultiBinding 的转换器以处理多种类型。在这种情况下,它需要处理布尔值和可见性。
ie, my convert function looks like this:
即,我的转换函数如下所示:
public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
var bools = values.Where( b => b is bool ).Cast<bool>();
var vis = values.Where( v => v is Visibility ).Cast<Visibility>();
// if no usable values, return unset
if( vis.Count() + bools.Count() == 0 )
return DependencyProperty.UnsetValue;
// if true, return visible
if( bools.All( b => b ) && vis.All( v => v == Visibility.Visible ) )
return Visibility.Visible;
// if false, see if hidden or collapsed is specified
var param = parameter as string;
Visibility ret;
if( Enum.TryParse( param, out ret ) )
return ret;
// default to collapsed
return Visibility.Collapsed;
}
This workaround should provide the behavior requested by specifying Visible for true and something else for false:
此解决方法应通过将 Visible 指定为 true 并将其他内容指定为 false 来提供请求的行为:
<MultiBinding Converter="{x:Static con:MultiAndToVisibilityConverter.Instance}">
<Binding Path="IsChecked" ElementName="CheckButton"/>
<Binding Path="RadioOne.IsChecked" FallbackValue="{x:Static Visibility.Visible}"
Converter="{x:Static con:BoolInverterConverter.Instance}"/>
</MultiBinding>

