bottus
bottus

Reputation: 903

BooleanToVisibilityConverter works on Textblock and not on UserControl

I'm working on a windows phone project. There is something i don't really understand about my xaml.

Here it is:

<Page
x:Class="CitiBox.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converters="using:CitiBox.Converters"
xmlns:views="using:CitiBox.Views"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
DataContext="{Binding Main, Source={StaticResource Locator}}">

<Page.Resources>
    <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Page.Resources>

<Grid>
    <!--<TextBlock Text="Test1" Visibility="{Binding Test2, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <TextBlock Text="Test2" Visibility="{Binding Test1, Converter={StaticResource BooleanToVisibilityConverter}}"/>-->
    <views:LoadingView Visibility="{Binding Test2, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <views:DrawerView Visibility="{Binding Test1, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>    
</Page>

As you can see there are two textblock that are commented and two views (user controls). You also can see that i binded the visibility of those four elements to two booleans with a BooleanToVisibilityConverter.

What surprises me is that if i test this code with the two textblocks, it works and if i try it with the views it doesn't. my views contains only a textblock with a message, nothing fancy..

Here is what they look like:

<UserControl
x:Class="CitiBox.Views.LoadingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CitiBox.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
DataContext="{Binding Loading, Source={StaticResource Locator}}">

<Grid>
    <TextBlock Text="Loading!!"/>
</Grid>
</UserControl>

Would you have an idea of what it could be ? Thanks in advance, Guillaume.

Upvotes: 1

Views: 1397

Answers (3)

mcdave
mcdave

Reputation: 52

The problem is the use of DataContext. Your MainPage has a DataContext :

DataContext="{Binding Main, Source={StaticResource Locator}}"

LoadingView also has a DataContext

So, when you write this code :

You try to find Test2 as a field in the DataContext of the LoadingView because you're in the same View. To avoid this behavior, you can try this :

<views:LoadingView Visibility="{Binding  ElementName=Page,Path=DataContext.Test2, Converter={StaticResource BooleanToVisibilityConverter}}"/>

Or you can write a class called NavigationService inherited from INavigationService (MVVM Light) Each view in your project will be a Page and you will be a transition (like fade) between all your pages

Upvotes: 1

Dinesh balan
Dinesh balan

Reputation: 495

I think your Problem is DataContext Because The Page DataContext is

DataContext="{Binding Main, Source={StaticResource Locator}}"

Where as You set usercontrol dataContext as DataContext="{Binding Loading, Source={StaticResource Locator}}" Try to Change Your Code Like this

<Page x:Class="CitiBox.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:converters="using:CitiBox.Converters"
      xmlns:views="using:CitiBox.Views"
      mc:Ignorable="d"
      Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
      DataContext="{Binding Main, Source={StaticResource Locator}}"
      x:Name="Page">

<Page.Resources>
   <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Page.Resources>

<Grid>
    <!--<TextBlock Text="Test1" Visibility="{Binding Test2, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <TextBlock Text="Test2" Visibility="{Binding Test1, Converter={StaticResource BooleanToVisibilityConverter}}"/>-->
    <views:LoadingView Visibility="{Binding  ElementName=Page,Path=DataContext.Test2, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <views:DrawerView Visibility="{Binding  ElementName=Page,Path=DataContext.Test1, Converter={StaticResourceBooleanToVisibilityConverter}}"/>
</Grid>    
</Page>

Upvotes: -1

Mike Eason
Mike Eason

Reputation: 9713

In your UserControl, you are explicitly setting the DataContext.

DataContext="{Binding Loading, Source={StaticResource Locator}}"

This means that the following binding will not work:

Visibility="{Binding Test2, Converter={StaticResource BooleanToVisibilityConverter}}"

The reason why is because the binding is looking for Test2 in the current DataContext of the UserControl. Instead, you need to be looking for Test2 in the parent control's DataContext.

Try this instead:

Visibility="{Binding DataContext.Test2, RelativeSource={RelativeSource AncestorType=Page}, Converter={StaticResource BooleanToVisibilityConverter}}"

Upvotes: 1

Related Questions