In this post, I briefly discuss the design behind the VisibilityControl
.
Posts in this series:
If you look at the source code history at codeplex, you will notice that I first designed this control with two dependency properties, one for the true content and one for the false content. The resulting XAML that the user needed to enter to use the control seems a bit clunky to me. Therefore, I switched to an ItemsControl-derived solution. I ask the user of the control to load the Items property with the false and true content respectively.
It does seem a bit weird to use a list to hold two and only two items, but there you have it. Maybe someday I can shore-up the sanity of this choice by making the control be able to display one of a series of items based upon the value of an
int
, enum
, or string
.
The only real thing to notice about the source below is to understand that we set the value of the dependency property called
VisibleContentto
the appropriate user interface element found in the list, based upon the value of
IsTrue
. The default style simply shows the content of VisibleContent
.
VisibilityControl.cs
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;
namespace VisibilityControlLibrary
{
[ContentProperty(Name = "Items")]
public class VisibilityControl : ItemsControl
{
public VisibilityControl()
{
this.DefaultStyleKey = typeof(VisibilityControl);
Items.VectorChanged += OnItemsChanged;
}
public bool IsTrue
{
get { return (bool)GetValue(IsTrueProperty); }
set { SetValue(IsTrueProperty, value); }
}
public static readonly DependencyProperty IsTrueProperty =
DependencyProperty.Register("IsTrue", typeof(bool),
typeof(VisibilityControl), new PropertyMetadata(null, OnIsTrueChanged));
public object VisibleContent
{
get { return (object)GetValue(VisibleContentProperty); }
private set { SetValue(VisibleContentProperty, value); }
}
public static readonly DependencyProperty VisibleContentProperty =
DependencyProperty.Register("VisibleContent", typeof(object),
typeof(VisibilityControl), new PropertyMetadata(null));
private static void OnIsTrueChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
var visibilityItemsControl = d as VisibilityControl;
if (visibilityItemsControl != null)
{
visibilityItemsControl.Evaluate();
}
}
void OnItemsChanged(IObservableVector<object> sender, IVectorChangedEventArgs evt)
{
Evaluate();
}
void Evaluate()
{
if (Items.Count >= 2)
{
VisibleContent = Items[IsTrue ? 1 : 0];
}
else
{
VisibleContent = null;
}
}
}
}
Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:VisibilityControlLibrary">
<Style
TargetType="local:VisibilityControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:VisibilityControl">
<Grid>
<ContentPresenter
Content="{TemplateBinding VisibleContent}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
John Hauck has been developing software professionally since 1981, and focused on Windows-based development since 1988. For the past 17 years John has been working at LECO, a scientific laboratory instrument company, where he manages software development. John also served as the manager of software development at Zenith Data Systems, as the Vice President of software development at TechSmith, as the lead medical records developer at Instrument Makar, as the MSU student who developed the time and attendance system for Dart container, and as the high school kid who wrote the manufacturing control system at Wohlert. John loves the Lord, his wife, their three kids, and sailing on Lake Michigan.