如何写一个<If>WPF XAML 的用户控件 [英] how to write an <If> user control for WPF XAML

查看:35
本文介绍了如何写一个<If>WPF XAML 的用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写用户控件方面取得了一些进展,该控件不仅隐藏内容,而且在不满足某些条件时将其完全删除.

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.

几个示例用例:

<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(...) 很容易证明).我想完全阻止内容运行,以防它尝试做一些繁重的工作,或者对尚不存在的数据进行操作等.

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.

这是我目前想到的:

    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 基本是空的;我将其包括在内,以防万一这里有重要的事情:

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.

推荐答案

我会使用 Custom Control 而不是 User Control 并使默认子项成为自定义 DependencyProperty并手动添加到控件的内容

I would use a Custom Control and not a User Control and make the default child a custom DependencyProperty and add to the control's content manually

[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>

这篇关于如何写一个&lt;If&gt;WPF XAML 的用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆