I have two controls contained within a data template. Control #1 is a TextBlock known as "TXTBLOCK". Control #2 is a TextBox known as "TXTBOX":
TXTBLOCK has Visibility set to TextBox Visibility using the converter to give the opposite value.
Example:
<TextBlock Name="TXTBLOCK" Visibility="{Binding ElementName=**TXTBOX**, Path=Visibility, Converter={StaticResource toggleVisConverter}}" />
<TextBox Name="TXTBOX" Visibility="{Binding ElementName=**TXTBLOCK**, Path=Visibility, Converter={StaticResource toggleVisConverter}}" />
Converter is:
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'.");
Now...to me this should be simple. Changing the visibility of one will set the other's visibility to false.
Not the case...
Works the very first time through and then the converter stops being called.
Even if I explicitly state: "TXTBOX.Visibility = Visibility.Hidden" in code behind, the converter never gets called.
What gives? What am I missing?
This is my first post on SO...so forgive me if I missed something or need to provide more info. I'll be happy to do it
Thanks!
It seems WPF has ways of detecting and avoiding stack overflows in data-binding. I'm aware of one, and it seems you've found another.
When you change the visibility of one of your controls, something like the following happens (in theory, at least):
This would go on forever and quite probably cause a stack overflow, if it weren't for WPF detecting situations such as this automatically. In this case it seems that it stops listening to the bindings you've created once it detects it could be heading towards a stack overflow.
I haven't run your code, but I suspect that WPF doesn't inform you about this either. I'm guessing there's no exceptions, warnings, nor even a debugging line written to the Output window.
It seems the pair of bindings is the problem here. What I recommend you do is:
ConvertBack
method. (If all your converter is doing is swapping between Collapsed
and Visible
, ConvertBack
can probably just call Convert
.)Mode=TwoWay
, and remove the other binding. A TwoWay
binding will be enough for communication in both directions between your two controls.EDIT: my comment about ConvertBack
was that you could implement it as follows:
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Convert(value, targetType, parameter, culture);
}
This is because all your converter is doing is swapping between Visible
and Collapsed
, and converting one way is the same as converting back. This comment was essentially an aside; you can of course implement ConvertBack
as you wish, but you will need to implement ConvertBack
if you are using your converter in a TwoWay
binding.