XAML中的条件块

时间:2012-10-21 16:49:59

标签: wpf xaml controls conditional

我想写一个条件控件如下:

<local:ConditionalBlock Condition={Binding CertainBoolValue}>
    <ConditionalBlock.Match>
        <!-- Any content here -->
    </ConditionalBlock.Match>
    <ConditionalBlock.Else>
        <!-- Any content here -->
    </ConditionalBlock.Else>
</local:ConditionalBlock>

目前我不知道应该如何实施。所以请帮忙。感谢

编辑

在等待响应的同时,我使用Custom Control&amp; amp;控制模板如下:

using System.Windows;
using System.Windows.Controls;

namespace Sample
{
    public class ConditionalControl : ContentControl
    {
        static ConditionalControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ConditionalControl), new FrameworkPropertyMetadata(typeof(ConditionalControl)));
        }

        public object Alternative
        {
            get { return (object)GetValue(AlternativeProperty); }
            set { SetValue(AlternativeProperty, value); }
        }

        public static readonly DependencyProperty AlternativeProperty =
            DependencyProperty.Register("Alternative", typeof(object), typeof(ConditionalControl), new UIPropertyMetadata(null));

        public bool Condition {
            get { return (bool)GetValue(ConditionProperty); }
            set { SetValue(ConditionProperty, value); }
        }

        public static readonly DependencyProperty ConditionProperty =
            DependencyProperty.Register("Condition", typeof(bool), typeof(ConditionalControl), new UIPropertyMetadata(null));
    }
}

ConditionalControl.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Sample">

    <Style TargetType="{x:Type local:ConditionalControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ConditionalControl}">
                    <Grid>
                        <ContentPresenter Name="match"/>
                        <ContentPresenter Name="alternative" ContentSource="Alternative" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="Condition" Value="True">
                            <Setter TargetName="match" Property="Visibility" Value="Visible"/>
                            <Setter TargetName="alternative" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="Condition" Value="False">
                            <Setter TargetName="match" Property="Visibility" Value="Collapsed"/>
                            <Setter TargetName="alternative" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

样本用法:

<Grid>
    <local:ConditionalControl Condition="{Binding CertainBoolValue}">
        <Label>Match case</Label>
        <local:ConditionalControl.Alternative>
            <Label>Alternative case</Label>
        </local:ConditionalControl.Alternative>
    </local:ConditionalControl>
</Grid>

无论如何,感谢Luke Woodward的快速回应。我会将你的答案标记为已接受

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是使用以下XAML创建UserControl:

<ContentControl x:Class="WpfApplication1.ConditionalBlock"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />

以及以下代码隐藏:

using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    public partial class ConditionalBlock : ContentControl
    {
        public static readonly DependencyProperty ConditionProperty =
            DependencyProperty.Register("Condition", typeof(bool), typeof(ConditionalBlock),
                                        new FrameworkPropertyMetadata(Condition_Changed));

        public ConditionalBlock()
        {
            InitializeComponent();
            Loaded += ((s, e) => UpdateContent());
        }

        public bool Condition
        {
            get { return (bool)GetValue(ConditionProperty); }
            set { SetValue(ConditionProperty, value); }
        }

        public object Match { get; set; }

        public object Else { get; set; }

        private static void Condition_Changed(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var conditionalBlock = obj as ConditionalBlock;
            if (conditionalBlock != null)
            {
                conditionalBlock.UpdateContent();
            }
        }

        private void UpdateContent()
        {
            Content = (Condition) ? Match : Else;
        }
    }
}

请注意,我们已将超类从UserControl更改为ContentControl

这为条件使用依赖项属性,以便在绑定值更改时得到通知。当条件发生变化时,我们通过分配从Content继承的ContentControl依赖项属性来更新哪些内容可见。最后,为了确保在首次显示控件时显示一个或其他内容,我们在Loaded事件的处理程序中更新内容。 (在构造函数中调用它不起作用,因为此时尚未设置MatchElse属性。)

我假设MatchElse属性的内容不会改变,所以我没有把它们作为依赖属性来实现。