0

I want to change the visibility of the TextBlock with a Binding depending on the state of the boolean variable of the code behind

<TextBlock Text="Hello">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsVisible}" Value="True">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

This don't work :(

    private bool _isVisible = false;
    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            _isVisible = value;
            NotifyPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  • Have you worked with [`inotifypropertyhanged`](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged?view=netcore-3.1) before? if not then I invite you to read about it. – Cfun May 20 '20 at 02:11
  • I don't understand, could you explain it to me with code? –  May 20 '20 at 02:13
  • [Simple small INotifyPropertyChanged implementation](https://stackoverflow.com/q/3851144/5228202) https://stackoverflow.com/q/5785265/5228202 you will find plenty of example if you make a little search. – Cfun May 20 '20 at 02:24
  • 1
    your variable name is wrong here: `public bool isVisible`, should be `IsVisible` – Cfun May 20 '20 at 03:05
  • 1
    @Cfun is right. This is one of the reasons you should use [`nameof`](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/nameof) and/or [`CallerMemberName`](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute). – Keith Stein May 20 '20 at 03:10
  • I edited the post, don't work with CallerMemberName –  May 20 '20 at 03:13
  • @user10438104 have you solve this issue? I'm facing the same issue as you, can you share how you solve this? – Ashley Hooithin Nov 20 '20 at 05:29

1 Answers1

2

The problem is within your propertyname IsVisible. You are in the CodeBehind of a Window or a UserControl, so there is already a property called IsVisible which comes from the Window/UserControl.

Just change the name of your property to something like IsCurrentlyVisible and your code will work.

If you have more places in your code where you have to set the Visibility of a control dependent on a bool-property I would recommend you to use a converter instead of the style.

The converter-class for converting a bool-value to a Visibility looks like:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace Playground
{
    internal class BoolToVisibilityConverter : MarkupExtension, IValueConverter
    {
        private static BoolToVisibilityConverter converter;

        // ReSharper disable once EmptyConstructor
        public BoolToVisibilityConverter()
        {

        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return converter ?? (converter = new BoolToVisibilityConverter());
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool b && b)
                return Visibility.Visible;
            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

And the usage of this converter is just as easy as:

<TextBlock Text="Hello" Visibility="{Binding IsCurrentlyVisible, Converter={local:BoolToVisibilityConverter}}"/>
Tomtom
  • 9,087
  • 7
  • 52
  • 95
  • How is this different from https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.booleantovisibilityconverter? – Klaus Gütter May 20 '20 at 05:01
  • It differs, because my converter is derived from `MarkupExtension`. So I don't need to create a resource for it. I can use it directly where I need it. – Tomtom May 20 '20 at 08:26