我已经在编写一个用户控件方面取得了一些进展,它不仅可以隐藏内容,而且可以在不满足某些条件时完全删除
。几个用例:
<mynamespace:If Condition="{Binding PerformingWork}">
<LoadingThrobber />
</mynamespace:If>
<mynamespace:If Condition="{Binding HasResults}">
<ItemsControl ...>
...
</ItemsControl>
</mynamespace:If>
或
<mynamespace:If Condition="{Binding UserHasMorePermissions}">
...
</mynamespace:If>
等。
我的解决方案似乎有效,但有一个严重的缺点:If "块"在被删除之前仍然加载一次(通过在某些子控件的构造函数中放置MessageBox.Show(…)很容易证明)。我想阻止内容运行,以防它试图做一些繁重的工作,或操作尚不存在的数据等。
这是我目前想到的:
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();
}
}
}
XAML基本为空;我把它包括进来只是为了以防这里有重要的东西:
<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>
当然,如果有另一种方法来实现同样的目标,那就太好了。
我会使用自定义控件而不是用户控件,并使默认子属性为自定义DependencyProperty并手动添加到控件的内容
[ContentProperty("ConditionalContent")]
public partial class If : ContentControl
{
public If()
{
Loaded += OnLoad;
}
private void OnLoad(object sender, RoutedEventArgs e)
{
update();
}
private void update()
{
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.update();
}
}
public object ConditionalContent
{
get { return (object)GetValue(ConditionalContentProperty); }
set { SetValue(ConditionalContentProperty, value); }
}
public static readonly DependencyProperty ConditionalContentProperty =
DependencyProperty.Register("ConditionalContent", typeof(object), typeof(If), new PropertyMetadata(null,OnConditionChangedCallback));
}
它是这样工作的
<local:If Condition="{Binding}">
sdgdfhsh <!-- or anything else! -->
</local:If>