【问题标题】:Visibility of two controls via data binding and value converter通过数据绑定和值转换器实现两个控件的可见性
【发布时间】:2012-08-23 11:12:41
【问题描述】:

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

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 上的第一篇文章......如果我遗漏了什么或需要提供更多信息,请原谅我。我很乐意这样做

谢谢!

【问题讨论】:

    标签: c# wpf data-binding visibility ivalueconverter


    【解决方案1】:

    似乎 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,但如果您在TwoWay 绑定中使用转换器,则需要实现ConvertBack

    【讨论】:

    • 奇怪 我想知道为什么我没有遇到堆栈溢出。我会尝试你的建议并回复。感谢回复
    • Luke 再次感谢您的回复。我看了看,我不确定我是否遵循你的建议。我已经从文本块中删除了绑定。我在 TextBOX 上做了绑定 TwoWay。我不确定我是否了解 ConvertBack。你真的是在说调用“Convert(?)”
    猜你喜欢
    • 2018-03-23
    • 2011-09-12
    • 1970-01-01
    • 2013-06-26
    • 2016-06-23
    • 2017-11-09
    • 2012-11-23
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多