【问题标题】:WPF UserControl creating multiple layout choicesWPF UserControl 创建多个布局选择
【发布时间】:2013-05-12 22:35:15
【问题描述】:

我有一个 UserControl,我定义了各种属性,因此我可以为屏幕上的每个副本自定义它。我有一个使用 LinearGradientBrush 填充的路径。目前,这被硬编码到 XAML 中。我已经将路径控件的宽度和可见性作为依赖对象,并且可以轻松修改这些:

<Path 
    Visibility="{TemplateBinding PathAVisibility}"
    Width="{TemplateBinding PathALength}">
        <LinearGradientBrush EndPoint="0,0.5" MappingMode="RelativeToBoundingBox" StartPoint="1,0.5">
            <GradientStop Color="#07FFFFFF" Offset="0.812"/>
            <GradientStop Color="Red"/>
            <GradientStop Color="#00000000" Offset="0.993"/>
            <GradientStop Color="#FF956666" Offset="0.62"/>
        </LinearGradientBrush>...

我想做的是创建一些渐变作为选项,然后我可以在 WPF XAML 设计器中选择它们作为属性。像“GradA”是红色的,“GradB”是蓝色的,但没有透明度,等等。

有了可见性,我可以在设计视图中看到“可见/隐藏/折叠”作为可供选择的选项,这就是我所追求的。

这就是我卡住的地方。我什至不知道这会被称为什么,或者如何接近它。

我应该看哪个方向的任何指针?

【问题讨论】:

    标签: wpf user-controls templatebinding


    【解决方案1】:

    您可以使用enumXaml 中提供您想要的固定值,然后您可以使用PropertyChangedCallback 上的enum DependencyProperty 来更改Brush

    这是一个非常快速的例子。

    代码:

    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            DataContext = this;
        }
    
        public BrushType BrushType
        {
            get { return (BrushType)GetValue(BrushTypeProperty); }
            set { SetValue(BrushTypeProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for BrushType.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BrushTypeProperty =
            DependencyProperty.Register("BrushType", typeof(BrushType), typeof(UserControl1)
            , new PropertyMetadata(BrushType.None, new PropertyChangedCallback(OnBrushTypeChanged)));
    
        private static void OnBrushTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var userControl = d as UserControl1;
            if (e.NewValue is BrushType)
            {
                userControl.MyBrush = userControl.FindResource(e.NewValue.ToString()) as Brush;
            }
        }
    
        public Brush MyBrush
        {
            get { return (Brush)GetValue(MyBrushProperty); }
            set { SetValue(MyBrushProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for MyBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyBrushProperty =
            DependencyProperty.Register("MyBrush", typeof(Brush), typeof(UserControl1), new PropertyMetadata(null));
    
    }
    
    public enum BrushType
    {
        None,
        BrushA,
        BrushB,
        BrushC
    }
    

    Xaml:

    <UserControl x:Class="WPFListBoxGroupTest.UserControl1"
                 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" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <SolidColorBrush x:Key="BrushA" Color="Red" />
            <SolidColorBrush x:Key="BrushB" Color="Yellow" />
            <SolidColorBrush x:Key="BrushC" Color="Blue" />
        </UserControl.Resources>
    
        <Grid Background="{Binding MyBrush}" />
    
    </UserControl>
    

    用法:

    <StackPanel Orientation="Horizontal">
        <local:UserControl1 BrushType="BrushA" />
        <local:UserControl1 BrushType="BrushB" />
        <local:UserControl1 BrushType="BrushC" />
    </StackPanel>
    

    结果:

    【讨论】:

    • 好的,所以我误以为我有一个用户控件,但实际上我没有一个 ResourceDictionary,然后我就有了一个基于该控件的控件。我已经研究了你的代码,这几乎是一种享受。未找到 BrushA/B/C 资源。如果我将它们作为页面资源放在页面级别,那么它会编译,但不会设置颜色。我会将您的答案标记为正确,因为它确实符合我的要求。我的错,我的电线交叉了。您能否建议我应该将 SolidcolorBrush 资源放在资源字典中的哪个位置?非常感谢您到目前为止所花费的时间。
    • 您可以将画笔放在控件中的任何位置,如果您只使用路径上的画笔,则可以放置在 或父容器中,如果您不使用UserControl你在用什么,所有FrameworkElements都有自己的资源
    • 谢谢。我会在周末对此进行更多研究,看看它会带我去哪里。
    【解决方案2】:

    视觉状态是一个很好的功能,可以最大程度地减少您的编码工作量。阅读有关它们的信息here。还有其他机制可以实现这一点。样式、模板和触发器的组合也可以使用,但会使访问组件代码中的 UI 元素变得更加困难。

    【讨论】:

    • 谢谢。当我来做我正在计划的图像动画时,它可能会对我有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多