Keven M
Keven M

Reputation: 992

BoolToVisibilityConverter not firing in UWP

I am completely stumped by this. I have a UserControl in UWP/C# that contains several Border objects which are meant to be doors to rooms. I have 4 DependencyProperties (one for each direction - N,S,E,W), with a type of bool, each of them connected to a BoolToVisibilityConverter. The concept is that the doors can be toogled between Visible and Collapsed by setting the HasDirectionDoor Property either true or false. As far as I can tell, everything is set up correctly, but it simply doesn't work. If I place a breakpoint on the Convert and ConvertBack methods of the BoolToVisConverter, those breakpoints never fire, meaning that it's not even reaching the Converter. Yet looking over what I've written, and comparing it to what I've found in various guides, everything looks identical and correct. Could somebody please look at the code, I'm sure it's something simple I'm missing, but I just can't see it.

BoolToVis:

namespace Crawler.Converters
{
    public class BoolToVisibilityConverter : IValueConverter
    {
        public BoolToVisibilityConverter()
        {

        }

        public object Convert(object value, Type targetType, object parameter, string language)
        {
            //return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;

            if (value is bool && (bool)value)
            {
                return Visibility.Visible;
            }
            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            return (value is Visibility && (Visibility)value == Visibility.Visible);
        }
    }
}

UserControl XAML:

<UserControl
    x:Class="Crawler.DungeonRoom"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Crawler"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:BooleanToVisibility="using:Crawler.Converters"
    mc:Ignorable="d" Background="White" Height="110" Width="110"
    d:DesignHeight="110" d:DesignWidth="110">
    <UserControl.Resources>
        <BooleanToVisibility:BoolToVisibilityConverter x:Key="BoolToVis" />         
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="5" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="5" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="5" />
        </Grid.RowDefinitions>
        <Border Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="4" Grid.RowSpan="4" Background="White" />
        <Border x:Name="westDoor" Grid.Column="0" Grid.Row="2" Grid.RowSpan="2" Background="SaddleBrown" Visibility="{Binding HasWestDoor, Converter={StaticResource ResourceKey=BoolToVis}}" />
        <Border x:Name="northDoor" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="2" Background="SaddleBrown" />
        <Border x:Name="eastDoor" Grid.Column="5" Grid.Row="2" Grid.RowSpan="2" Background="SaddleBrown" />
        <Border x:Name="southDoor" Grid.Column="2" Grid.Row="5" Grid.ColumnSpan="2" Background="SaddleBrown" />
        <Border x:Name="roomIcon" Grid.Column="4" Grid.Row="1" BorderBrush="DimGray" BorderThickness="1 0 0 1">
            <Image Source="Assets\MapTiles\Camp.png" />
        </Border>
    </Grid>
</UserControl>

UserControl C#:

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Crawler
{
    public sealed partial class DungeonRoom : UserControl
    {
        public static readonly DependencyProperty HasWestDoorProperty =
            DependencyProperty.Register("HasWestDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty HasNorthDoorProperty =
            DependencyProperty.Register("HasNorthDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty HasEastDoorProperty =
            DependencyProperty.Register("HasEastDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty HasSouthDoorProperty =
            DependencyProperty.Register("HasSouthDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.Register("Type", typeof(RoomType), typeof(DungeonRoom), new PropertyMetadata(0));

        public bool HasWestDoor
        {
            get { return (bool)GetValue(HasWestDoorProperty); }
            set { SetValue(HasWestDoorProperty, value); }
        }
        public bool HasNorthDoor
        {
            get { return (bool)GetValue(HasNorthDoorProperty); }
            set { SetValue(HasNorthDoorProperty, value); }
        }

        public bool HasEastDoor
        {
            get { return (bool)GetValue(HasEastDoorProperty); }
            set { SetValue(HasEastDoorProperty, value); }
        }

        public bool HasSouthDoor
        {
            get { return (bool)GetValue(HasSouthDoorProperty); }
            set { SetValue(HasSouthDoorProperty, value); }
        }

        public RoomType Type
        {
            get { return (RoomType)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }

        public DungeonRoom()
        {
            this.InitializeComponent();
        }
    }
}

Upvotes: 1

Views: 617

Answers (1)

mm8
mm8

Reputation: 169340

Your binding probably fails because you haven't set the source for it or set the DataContext of the Border to the UserControl where the source property is defined.

Try to give the UserControl a Name and bind to it using the ElementName property:

<UserControl .... Name="uc">
...
    <Border x:Name="westDoor" ... Visibility="{Binding HasWestDoor, ElementName=uc,
         Converter={StaticResource ResourceKey=BoolToVis}}" />

Or use a compiled binding:

<Border x:Name="westDoor" ... Visibility="{x:Bind HasWestDoor, Mode=OneWay,
     Converter={StaticResource ResourceKey=BoolToVis}}" />

This should give you a compilation error if the binding fails.

Upvotes: 2

Related Questions