[Windows] How to add IsVisible Property to all WinRT UIElement
While developing apps with XAML and C#, you will definitely run into cases where you have to set the Visibility property, and this property has 2 values: Visible/Collapsed. And to bind to it with a bool, you have to use a converter. So why didn’t Microsoft design it to use a bool from the start? And is there a way around it?
This post is adapted from: http://www.rudyhuyn.com/blog/2015/03/26/how-to-add-isvisible-property-to-all-winrt-ui-elements/
History
The Visibility property inherited its values from WPF, which has 3 values:
- Visible: shows the control
- Hidden: doesn’t show the control, but keeps its space in the UI (like Opacity = 0, Visibility = Visible)
- Collapsed: doesn’t show the control and doesn’t keep its space in the UI either.
Moving to Silverlight, and later Windows RT on Windows 8.1 and Windows Phone 8.1, the hidden value was dropped — but since they still share the Windows NT kernel, Microsoft didn’t change the value to a bool and kept the 2 old values
The workaround
Here is a small class that lets you add a property called “IsVisible” to UIElements and pass it a true or false value
public class Extension : DependencyObject
{
public static readonly DependencyProperty IsVisibleProperty =
DependencyProperty.RegisterAttached("IsVisible",
typeof(bool),
typeof(Extension),
new PropertyMetadata(true, IsVisibleCallback));
private static void IsVisibleCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((UIElement)d).Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed;
}
public static void SetIsVisible(UIElement element, bool value)
{
element.SetValue(IsVisibleProperty, value);
}
public static bool GetIsVisible(UIElement element)
{
return (bool)element.GetValue(IsVisibleProperty);
}
}
That’s it, you can use it right away
<Page x:Class="IsVisibleSample.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:ext="using:Huyn"
mc:Ignorable="d">
<Rectangle Height="100"
Width="100"
Fill="Red"
x:Name="Rectangle"
ext:Extension.IsVisible="false"/>
</Page>
Or use Binding with it
<CheckBox x:Name="MyCheckBox"
IsChecked="True"
Content="show rectangle"/>
<Rectangle Height="100"
Width="100"
Fill="Red"
x:Name="Rectangle"
ext:Extension.IsVisible="{Binding IsChecked,ElementName=MyCheckBox}"/>
Or use it as a Binding Source
<CheckBox IsChecked="{Binding (ext:Extension.IsVisible),ElementName=Rectangle}"
IsEnabled="False"
Content="rectangle is visible?"/>
Or use it in the code behind
var val = Extension.GetIsVisible(Rectangle);
Extension.SetIsVisible(Rectangle,true);
And that’s it