none
[XAML][VB][UWP]Opposite Visibility Converter

    Question

  • I have many scenarios in which I want one element to be visible when another is collapsed (or reverse). Rather than set both elements' Visibility in codebehind, I figured I would make a converter that between Visibility.Visible and Visibility.Collapsed. Here is my converter:

    Public Class VisibilityNotConverter : Implements IValueConverter
    	Public Function Convert(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.Convert
    		Return If(CType(value, Visibility) = Visibility.Visible, Visibility.Collapsed, Visibility.Visible)
    	End Function
    	Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.ConvertBack
    		Return If(CType(value, Visibility) = Visibility.Visible, Visibility.Collapsed, Visibility.Visible)
    	End Function
    End Class

    However, this does not seem to be working. When I use this, my XAML includes the following:

    Visibility="{Binding Visibility,ElementName=btnStart,Converter={StaticResource VisibilityNot}}"

    I seem to remember using something like this in the past, am I doing something wrong here? Is Visibility not allowed to be the source of a Binding? Thanks.


    Nathan Sokalski njsokalski@hotmail.com http://www.nathansokalski.com/

    Tuesday, May 21, 2019 7:08 PM

All replies

  • Hi,

    Well, did it work at the beginning, I mean the visibility of the control is correctly according to another control's visibility when you just loaded the control? The xaml binding is correct. I'm not familiar with VB but could you make sure the output value of the Convert function is correctly? Because I do not know how you set the binding for the source control. I just made a sample here. You could refer it.

    Xaml:

       <Page.Resources>
            <local:TestConverter x:Key="ValueConverter"/>
        </Page.Resources>
        <StackPanel>
            <Rectangle x:Name="RedOne" Fill="Red" Width="200" Height="200" Visibility="{Binding Test,Mode=TwoWay}"/>
            <Rectangle x:Name="BlueOne" Fill="Blue" Width="200" Height="200" Visibility="{Binding Visibility,ElementName=RedOne,Converter={StaticResource ValueConverter}}"/>
            <Button Content="Click" Click="Button_Click"/>
        </StackPanel>

    Code behind:

      private Visibility test;
            public Visibility Test {
                get
                {
                    return test;
                }
                set
                {
                    if (value != test)
                    {
                        test = value;
                        OnPropertyChanged("Test");
                    }
         
                }
            }
            public MainPage()
            {
                this.InitializeComponent();
                Test = Visibility.Visible;
                this.DataContext = this;
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Test = Test.Equals(Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
            }

    And the converter:

     public class TestConverter:IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                Visibility visvalue = (Visibility)value;
              
                return visvalue.Equals(Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                Visibility visvalue = (Visibility)value;
    
                return visvalue.Equals(Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
            }
        }

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, May 22, 2019 4:30 AM
    Moderator
  • Hi I've had the same issue and solved it using x:bind and a wrapped bool.

    This is a c# wrapped bool

    public class WrappedBool {
    
            private bool value = false;
    
            public bool Default => value; 
            public bool Opposite => !value;
    
            public WrappedBool(bool b) => value = b;
    
            public static implicit operator WrappedBool(bool b) => new WrappedBool(b);
    
            public static implicit operator bool(WrappedBool b) => b.value;
    
    
        }

    create a property

    private My.WrappedBool property;
        public My.WrappedBool Property {
          get => property;
          set { property = value; OnPropertyChanged(nameof(Property)); }
        }

    and bind in xaml

    <Button Visibility="{x:Bind viewmodel.Property.Default, Mode=OneWay}"/>
        <Button Visibility="{x:Bind viewmodel.Property.Opposite, Mode=OneWay}"/>

    Another option is to use WindowsStateTriggers  with the visual state manager to trigger different visual states based on a boolean value.

    Hope this helps

    Good luck.

    Wednesday, May 22, 2019 1:10 PM