I've made some progress writing a user control which doesn't just hide content, but completely removes it, if some condition isn't met.
a couple example use cases:
<mynamespace:If Condition="{Binding PerformingWork}">
<LoadingThrobber />
</mynamespace:If>
<mynamespace:If Condition="{Binding HasResults}">
<ItemsControl ...>
...
</ItemsControl>
</mynamespace:If>
or
<mynamespace:If Condition="{Binding UserHasMorePermissions}">
...
</mynamespace:If>
etc.
my solution APPEARS to work, but has a serious downside: the contents of the If "block" are still loaded once, before being removed (easily proved by putting a MessageBox.Show(...) in some child control's constructor). I want to prevent the content from running AT ALL, in case it's trying to do some heavy work, or operate on data that doesn't yet exist, etc.
here's what I've come up with so far:
public partial class If : UserControl
{
private object ConditionalContent { get; set; }
public If()
{
InitializeComponent();
Loaded += OnLoad;
}
private void OnLoad(object sender, RoutedEventArgs e)
{
ConditionalContent = Content;
Loaded -= OnLoad;
OnConditionChanged();
}
private void OnConditionChanged()
{
Content = Condition ? ConditionalContent : null;
}
// === component properties
// omg, WPF
public bool Condition
{
get { return (bool)GetValue(ConditionProperty); }
set { SetValue(ConditionProperty, value); }
}
public static readonly DependencyProperty ConditionProperty = DependencyProperty.Register("Condition", typeof(bool), typeof(If), new PropertyMetadata(OnConditionChangedCallback));
private static void OnConditionChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (sender is If s)
{
s.OnConditionChanged();
}
}
}
the XAML is basically empty; I'm including it juuuust in case there's something important here:
<UserControl x:Class="XamlExtensions.If"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XamlExtensions"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
</UserControl>
of course, if there's another way to accomplish the same goal, that'd be great.