user3812509
user3812509

Reputation: 131

BooleanToVisibilityConverter not working properly

I have following MainWindow.xaml file, where I have defined ConnectionStatus.cs file as DataContext. I want to hide the "AccView" UserControl if there is no connection to an external device:

<Window x:Class="Overvaagning.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vw="clr-namespace:Overvaagning.View"
    xmlns:vm="clr-namespace:Overvaagning.ViewModel"
    Title="MainWindow" Height="619.631" Width="790.181">
<Window.Resources>
    <ResourceDictionary>
        <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="View\resStyles.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

<Window.DataContext>
    <vm:ConnectionStatus/>
</Window.DataContext>

<Grid Background="{StaticResource brushMainWindow}">
    <vw:AccView x:Name="AccView" Margin="0,10,96,141" Visibility="{Binding Path=UserControlVisible, Converter={StaticResource BoolToVisConverter}}" />
</Grid>

and my ConnectionStatus.cs class is as follows:

public class ConnectionStatus : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public connModel ConStatus { get; set; }

    public ConnectionStatus()
    {
        ConStatus = new connModel();
        ConStatus.PropertyChanged += con_PropertyChanged;
        ConStatus.countDevices(); 
    }



    private bool _userControlVisible = false;
    public bool UserControlVisible
    {
        get { return _userControlVisible; }
        set
        {
            if (value != _userControlVisible)
            {
                _userControlVisible = value;
                OnPropertyChanged("UserControlVisible");
            }
        }
    }

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

    private void con_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "statusVisible":
                UserControlVisible = ConStatus.statusVisible;
                break;
        }

    }
}

During startup, the bool UserControlVisible is actually changed to true from false and even though the OnpropertyChanged method is triggered, the MainWindow.xaml file does not show the UserControl. It is still "hidden". Where does the problem occur ?.

the connModel.cs class:

public class connModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    public connModel()
    {

    }

    public bool statusVisible { get; set; }

    public async void countDevices()
    {
        var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));
        if (devices.Count == 0)
        {
            statusVisible = false;

        }
        else 
        {
            statusVisible = true;            
        }
        OnPropertyChanged("statusVisible");
        OnPropertyChanged("Status");
    }

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

 }

Upvotes: 1

Views: 3045

Answers (2)

piofusco
piofusco

Reputation: 239

I think it would help if you could post your VM code. Here's some ideas.

I have always had trouble using a ResourceDictionary AND something else in the same View/UserControl/etc. Traditionally, I will put all my converters in my dictionaries. Perhaps, you should do the same. For example, take it out from here

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="View\resStyles.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

And put it in your ResourceDictionary like so. You should be able to copy and paste it directly like this

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />

   ...

</ResourceDictionary>

Additionally, boolean values default to false: http://msdn.microsoft.com/en-us/library/83fhsxwc.aspx. Hope this helps.

Upvotes: 0

OronDF343
OronDF343

Reputation: 518

For some reason bindings to members of other classes don't work. Here is what works for me:

In the C# code of the window, create a public property which points to your ConnectionStatus, for example:

public class MainWindow : Window
{
    // ...

    public ConnectionStatus CurrentConnectionStatus
    {
        get { return _myConnectionStatus; }
        // set is optional
    }
}

The property must not be auto-implemented.

Instead of setting the data context of your window, set the x:Name property to something, for example "MainWindowObj", set the ElementName of the binding to this value, and add the name of your property to the path, for example:

<Window ...
        x:Name="MainWindowObj">
    ...
        <vw:AccView ... Visibility="{Binding ElementName=MainWindowObj, Path=CurrentConnectionStatus.UserControlVisible, Converter={StaticResource BoolToVisConverter}}"/>

Upvotes: 1

Related Questions