【问题标题】:Why the Dependency Property can no be use in usercontrol?为什么依赖属性不能在用户控件中使用?
【发布时间】:2019-04-04 03:39:12
【问题描述】:

我想制作一个全新的按钮,因此我创建了一个继承 Button 的用户控件来执行此操作。 这是 XAML:

<Button x:Class="Uploader.PropertyButtonControl"
             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:Uploader"               
             mc:Ignorable="d" 
        xmlns:s="clr-namespace:Svg2Xaml;assembly=Svg2Xaml"
             d:DesignHeight="450" d:DesignWidth="800">
    <Button.Template>
        <ControlTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.6*"></RowDefinition>
                    <RowDefinition Height="0.4*"></RowDefinition>
                </Grid.RowDefinitions>
                <Border Width="{Binding Path=ActualHeight,RelativeSource={RelativeSource Self}}" Grid.RowSpan="2" Background="{Binding IconBackground,Mode=TwoWay}">
                    <s:SvgShape Source="{Binding IconSource,Mode=TwoWay}"></s:SvgShape>
                </Border>
                <TextBlock Grid.Column="1" Text="{Binding ButtonTitle,Mode=TwoWay}"></TextBlock>
                <TextBlock Grid.Column="1" Grid.Row="1" Foreground="#575757" Text="{Binding ButtonContent,Mode=TwoWay}"></TextBlock>
                <Border Grid.ColumnSpan="2" Grid.RowSpan="2" BorderBrush="#cecece" BorderThickness="1" Visibility="Collapsed" Name="Bo"></Border>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter TargetName="Bo" Property="Visibility" Value="Visible"></Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Button.Template>
</Button>

这里是代码隐藏:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Uploader
{
    /// <summary>
    /// Interaction logic for PropertyButtonControl.xaml
    /// </summary>
    public partial class PropertyButtonControl : Button
    {
        public PropertyButtonControl()
        {
            InitializeComponent();
        }


        public SolidColorBrush IconBackground
        {
            get { return (SolidColorBrush)GetValue(IconBackgroundProperty); }
            set { SetValue(IconBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IconBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IconBackgroundProperty =
            DependencyProperty.Register("IconBackground", typeof(SolidColorBrush), typeof(PropertyButtonControl),null);



        public ImageSource IconSource
        {
            get { return (ImageSource)GetValue(IconSourceProperty); }
            set { SetValue(IconSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IconSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IconSourceProperty =
            DependencyProperty.Register("IconSource", typeof(ImageSource), typeof(PropertyButtonControl), null);



        public string ButtonTitle
        {
            get { return (string)GetValue(ButtonTitleProperty); }
            set { SetValue(ButtonTitleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ButtonTitle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ButtonTitleProperty =
            DependencyProperty.Register("ButtonTitle", typeof(string), typeof(PropertyButtonControl), null);



        public string ButtonContent
        {
            get { return (string)GetValue(ButtonContentProperty); }
            set { SetValue(ButtonContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ButtonContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ButtonContentProperty =
            DependencyProperty.Register("ButtonContent", typeof(string), typeof(PropertyButtonControl), null);


    }
}

如果我在页面中使用它:

<local:PropertyButtonControl IconBackground="Red" ButtonTitle="123" ButtonContent="456"></local:PropertyButtonControl>

程序运行后,内容不显示,颜色不变化?好像是绑定问题。

但这有什么问题呢?谢谢。

【问题讨论】:

    标签: wpf


    【解决方案1】:

    您的问题是UserControl 不适用于全新按钮。 您应该使用CustomControlRead this if you want more details.

    我们的做法如下:

    在单独的文件中创建一个继承自Button 控件的新类PropertyButtonControl.cs

    public class PropertyButtonControl : Button
    {
    //No need for Constructor and InitializeComponent
    
        public SolidColorBrush IconBackground[...]
        public static readonly DependencyProperty IconBackgroundProperty =
            DependencyProperty.Register("IconBackground", typeof(SolidColorBrush), typeof(PropertyButtonControl), null);
    
        public ImageSource IconSource[...]
        public static readonly DependencyProperty IconSourceProperty =
            DependencyProperty.Register("IconSource", typeof(ImageSource), typeof(PropertyButtonControl), null);
    
        public string ButtonTitle[...]
        public static readonly DependencyProperty ButtonTitleProperty =
            DependencyProperty.Register("ButtonTitle", typeof(string), typeof(PropertyButtonControl), null);
    
        public string ButtonContent[...]
        public static readonly DependencyProperty ButtonContentProperty =
            DependencyProperty.Register("ButtonContent", typeof(string), typeof(PropertyButtonControl), null);
    }
    

    在单独的文件中创建一个包含 XAML 模板的 ResourceDictionaryPropertyButtonControl.xaml

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:view="clr-namespace:StackTest.View">
    
    <Style TargetType="{x:Type view:PropertyButtonControl }">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="auto"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="0.6*"/>
                            <RowDefinition Height="0.4*"/>
                        </Grid.RowDefinitions>
                        <Border Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"
                                Grid.RowSpan="2"
                                Background="{Binding Path=IconBackground, RelativeSource={RelativeSource AncestorType=view:PropertyButtonControl}}">
                        </Border>
                        <TextBlock Grid.Column="1"
                                   Text="{Binding Path=ButtonTitle, RelativeSource={RelativeSource AncestorType=view:PropertyButtonControl}}"/>
                        <TextBlock Grid.Column="1"
                                   Grid.Row="1"
                                   Foreground="#575757"
                                   Text="{Binding Path=ButtonContent, RelativeSource={RelativeSource AncestorType=view:PropertyButtonControl}}"/>
                        <Border Grid.ColumnSpan="2"
                                Grid.RowSpan="2"
                                BorderBrush="#cecece"
                                BorderThickness="1"
                                Visibility="Collapsed"
                                Name="Bo"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="Bo" Property="Visibility" Value="Visible"></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    </ResourceDictionary>
    

    将此资源字典添加到您的 App.XAML 资源中:

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="View/PropertyButtonControl.xaml"/>
             </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
    

    享受您的控制:

    <local:PropertyButtonControl IconBackground="Blue" ButtonTitle="123" ButtonContent="456"/>
    

    我将所有文件放在一个名为 View 的文件夹中。您必须根据自己的结构调整它。

    【讨论】:

    • 好吧,我总是把customcontrol和usercontrol搞不清楚,现在我想我知道它们之间的区别了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多