Faby
Faby

Reputation: 21

XAML Visibility Binding not working unless set in xaml.cs

I've been trying to set up a "downloading..." popup as a rectangle with its visibility set programmatically in the related viewModel. If I set the boolean in the xaml.cs file it works perfectly but obviously it needs to be set in the viewmodel and it just won't change its visibility if done so.

I've checked on previous solutions involving raising the propertyChanged event and setting the binding two-way.

<Rectangle 
    Width="400" 
    Height="200"
    x:Name="popup" 
    Fill="Red" 
    Visibility="{Binding PopupIsVisible, Converter={StaticResource ResBoolToVisibilityConverter}, UpdateSourceTrigger=PropertyChanged,         Mode=TwoWay}" />


private bool popupIsVisible;
public bool PopupIsVisible
{
    get { return popupIsVisible; }
    set
    {
         Set(ref popupIsVisible, value);
         RaisePropertyChanged("PopupIsVisible");
    }
}

EDIT: as requested, here's the Converter

public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        bool val;
        try
        {
            val = (bool)value;
        }
        catch (Exception)
        {
            return Visibility.Visible;
        }

        if(val)
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Hidden;
        }

    }

EDIT2: The popup should be visibile either by pressing a button or by waiting 10 seconds on the view, oddly enough it gets shown only with the second scenario which is launched with the following code:

        worker = Task.Factory.StartNew(() =>
        {
            while (cycle)
            {
                // Check for cancellation 
                cancellationToken.ThrowIfCancellationRequested();

                LoadProcessList();

                Task.Delay(TIME_TO_REFRESH).Wait();
            }

        }, cancellationToken);

Any ideas?

FINAL EDIT I managed to solve it by encasing the function containing the changes to the boolean as below:

        Task.Run(() =>
        {
            LoadProcessList();
        });

thanks to @lionthefox for pointing me in the right direction!

Upvotes: 1

Views: 1460

Answers (1)

Umar
Umar

Reputation: 487

It seems like there's something wrong with your binding OR the boolean to visibility converter. Here's an example that is working perfectly.

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private bool popupIsVisible;
    public bool PopupIsVisible
    {
        get
        {
            return popupIsVisible;
        }
        set
        {
            popupIsVisible = value;
            OnPropertyChanged("PopupIsVisible");
        }
    }


    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Following is the XAML code,

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="ResBoolToVisibilityConverter" />
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="60"/>
        <ColumnDefinition Width="100" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="60"/>
    </Grid.RowDefinitions>
    <Rectangle Width="400" Height="200"x:Name="popup" Fill="Red" Visibility="{BindingPopupIsVisible, Converter={StaticResource ResBoolToVisibilityConverter}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
    <Button Grid.Column="1" Content="Toggle" Click="Button_Click"/>
</Grid>

It is working here.

Upvotes: 1

Related Questions