通过数据绑定和值转换器可以看到两个控件

时间:2012-08-28 21:33:17

标签: c# wpf data-binding visibility ivalueconverter

我在数据模板中包含两个控件。控件#1是一个称为“TXTBLOCK”的TextBlock。 Control#2是一个名为“TXTBOX”的TextBox:

TXTBLOCK使用转换器将Visibility设置为TextBox Visibility,以提供相反的值。

示例:

<TextBlock Name="TXTBLOCK" Visibility="{Binding ElementName=**TXTBOX**, Path=Visibility, Converter={StaticResource toggleVisConverter}}" />

<TextBox Name="TXTBOX" Visibility="{Binding ElementName=**TXTBLOCK**, Path=Visibility, Converter={StaticResource toggleVisConverter}}" />

转换器是:

        if (targetType == typeof(Visibility))
        {
            Visibility vis = (Visibility)value;
            if (vis == Visibility.Collapsed)
            {
                return Visibility.Visible;
            }
            else
            {
                return Visibility.Collapsed;
            }
            //var vis == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
        }

        //return vis;
        throw new InvalidOperationException("Value must be of type 'Visibility'.");

现在......对我来说这应该很简单。更改一个的可见性会将另一个的可见性设置为false。

不是这样......

第一次工作,然后转换器停止被调用。

即使我在代码中明确声明:“TXTBOX.Visibility = Visibility.Hidden”,转换器也永远不会被调用。

是什么给出的?我错过了什么?

这是我关于SO的第一篇文章...如果我错过了某些内容或需要提供更多信息,请原谅我。我很乐意这样做

谢谢!

1 个答案:

答案 0 :(得分:0)

WPF似乎有办法检测和避免数据绑定中的堆栈溢出。 I'm aware of one,似乎你找到了另一个。

当您更改其中一个控件的可见性时,会发生以下情况(至少在理论上):

  • 您可以更改TextBlock的可见性(比如说),
  • 这会导致TextBox的可见性发生变化,
  • 这会导致TextBlock的可见性发生另一次变化,
  • 这会再次使用第一个绑定
  • 导致TextBlock的可见性发生另一次更改
  • ...

这将永远持续下去并且很可能导致堆栈溢出,如果不是WPF自动检测到这种情况。在这种情况下,一旦检测到它可能正朝向堆栈溢出,它似乎停止侦听您创建的绑定。

我没有运行你的代码,但我怀疑WPF也没有通知你。我猜测没有例外,警告,甚至没有写入输出窗口的调试行。

看来这对绑定是问题所在。我建议你做的是:

  • 通过实施ConvertBack方法,使ValueConverter成为双向转换器。 (如果您的所有转换器都在CollapsedVisible之间进行交换,ConvertBack可能只能调用Convert。)
  • 通过添加Mode=TwoWay双向进行其中一个绑定(无关紧要),并删除另一个绑定。 TwoWay绑定足以在两个控件之间进行双向通信。

编辑:我对ConvertBack的评论是您可以按照以下方式实施:

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    return Convert(value, targetType, parameter, culture);
}

这是因为你的所有转换器都在VisibleCollapsed之间进行交换,而转换一种方式与转换回来的方式相同。这个评论基本上是旁白;您当然可以根据需要实施ConvertBack,但如果您在ConvertBack绑定中使用转换器,则需要实施TwoWay