zoukankan      html  css  js  c++  java
  • WPF自定义控件 依赖属性绑定

    控件cs文件

    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Markup;
    using System.Windows.Media;
    
    namespace Controls
    {
    
        [TemplatePart(Name = "PART_DropDown", Type = typeof(System.Windows.Controls.Button))]
        [ContentProperty("Items")]
        [DefaultProperty("Items")]
        public class MyButton: System.Windows.Controls.Button
        {
            public static readonly DependencyProperty HorizontalOffsetProperty;
            public static readonly DependencyProperty IsContextMenuOpenProperty;
            public static readonly DependencyProperty ModeProperty;
            public static readonly DependencyProperty PlacementProperty;
            public static readonly DependencyProperty PlacementRectangleProperty;
            public static readonly DependencyProperty VerticalOffsetProperty;
    
            public static readonly DependencyProperty ImageSourceProperty =
                  DependencyProperty.Register("ImageSource", typeof(string), typeof(MyButton), new PropertyMetadata(""));
            public static readonly DependencyProperty ImageSourceChangeProperty =
                  DependencyProperty.Register("ImageSourceChange", typeof(string), typeof(MyButton), new PropertyMetadata(""));
    
    /// <summary>
            /// Static Constructor
            /// </summary>
            static MyButton()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
                IsContextMenuOpenProperty = DependencyProperty.Register("IsContextMenuOpen", typeof(bool), typeof(MyButton), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsContextMenuOpenChanged)));
                ModeProperty = DependencyProperty.Register("Mode", typeof(MyButtonMode), typeof(MyButton), new FrameworkPropertyMetadata(MyButtonMode.Split));
    
    
                PlacementProperty = ContextMenuService.PlacementProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(PlacementMode.Bottom, new PropertyChangedCallback(OnPlacementChanged)));
                PlacementRectangleProperty = ContextMenuService.PlacementRectangleProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(Rect.Empty, new PropertyChangedCallback(OnPlacementRectangleChanged)));
                HorizontalOffsetProperty = ContextMenuService.HorizontalOffsetProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnHorizontalOffsetChanged)));
                VerticalOffsetProperty = ContextMenuService.VerticalOffsetProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnVerticalOffsetChanged)));
            }
    
    
            /*
             * Overrides
             * 
            */
            /// <summary>
            /// OnApplyTemplate override, set up the click event for the dropdown if present in the template
            /// </summary>
            public override void OnApplyTemplate()
            {
                base.OnApplyTemplate();
    
                // set up the click event handler for the dropdown button
                System.Windows.Controls.Primitives.ButtonBase dropDown = this.Template.FindName("PART_DropDown", this) as System.Windows.Controls.Primitives.ButtonBase;
                if (dropDown != null)
                    dropDown.Click += Dropdown_Click;
            }
    
            /// <summary>
            ///     Handles the Base Buttons OnClick event
            /// </summary>
            protected override void OnClick()
            {
                switch (Mode)
                {
                    case MyButtonMode.Dropdown:
                        OnDropdown();
                        break;
    
                    default:
                        base.OnClick(); // forward on the Click event to the user
                        break;
                }
            }
    
            /*
             * Properties
             * 
            */
    
    
            /// <summary>
            /// The Split Button's Items property maps to the base classes ContextMenu.Items property
            /// </summary>
            public ItemCollection Items
            {
                get
                {
                    EnsureContextMenuIsValid();
                    return this.ContextMenu.Items;
                }
            }
    
            /*
             * DependencyProperty CLR wrappers
             * 
            */
    
            public string ImageSource
            {
                get { return (string)GetValue(ImageSourceProperty); }
                set { SetValue(ImageSourceProperty, value); }
            }
    
            public string ImageSourceChange
            {
                get { return (string)GetValue(ImageSourceChangeProperty); }
                set { SetValue(ImageSourceChangeProperty, value); }
            }
    
    /// <summary>
            /// Gets or sets the IsContextMenuOpen property. 
            /// </summary>
            public bool IsContextMenuOpen
            {
                get { return (bool)GetValue(IsContextMenuOpenProperty); }
                set { SetValue(IsContextMenuOpenProperty, value); }
            }
    
    
            /// <summary>
            /// Placement of the Context menu
            /// </summary>
            public PlacementMode Placement
            {
                get { return (PlacementMode)GetValue(PlacementProperty); }
                set { SetValue(PlacementProperty, value); }
            }
    
    
            /// <summary>
            /// PlacementRectangle of the Context menu
            /// </summary>
            public Rect PlacementRectangle
            {
                get { return (Rect)GetValue(PlacementRectangleProperty); }
                set { SetValue(PlacementRectangleProperty, value); }
            }
    
    
            /// <summary>
            /// HorizontalOffset of the Context menu
            /// </summary>
            public double HorizontalOffset
            {
                get { return (double)GetValue(HorizontalOffsetProperty); }
                set { SetValue(HorizontalOffsetProperty, value); }
            }
    
    
            /// <summary>
            /// VerticalOffset of the Context menu
            /// </summary>
            public double VerticalOffset
            {
                get { return (double)GetValue(VerticalOffsetProperty); }
                set { SetValue(VerticalOffsetProperty, value); }
            }
    
            /// <summary>
            /// Defines the Mode of operation of the Button
            /// </summary>
            /// <remarks>
            ///     The MyButton two Modes are
            ///     Split (default),    - the button has two parts, a normal button and a dropdown which exposes the ContextMenu
            ///     Dropdown            - the button acts like a combobox, clicking anywhere on the button opens the Context Menu
            /// </remarks>
            public MyButtonMode Mode
            {
                get { return (MyButtonMode)GetValue(ModeProperty); }
                set { SetValue(ModeProperty, value); }
            }
    
            /*
             * DependencyPropertyChanged callbacks
             * 
            */
    
            private static void OnIsContextMenuOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                MyButton s = (MyButton)d;
                s.EnsureContextMenuIsValid();
    
                if (!s.ContextMenu.HasItems)
                    return;
    
                bool value = (bool)e.NewValue;
    
                if (value && !s.ContextMenu.IsOpen)
                    s.ContextMenu.IsOpen = true;
                else if (!value && s.ContextMenu.IsOpen)
                    s.ContextMenu.IsOpen = false;
            }
    
    
            /// <summary>
            /// Placement Property changed callback, pass the value through to the buttons context menu
            /// </summary>
            private static void OnPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                MyButton s = d as MyButton;
                if (s == null) return;
    
                s.EnsureContextMenuIsValid();
                s.ContextMenu.Placement = (PlacementMode)e.NewValue;
            }
    
            /// <summary>
            /// PlacementRectangle Property changed callback, pass the value through to the buttons context menu
            /// </summary>
            private static void OnPlacementRectangleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                MyButton s = d as MyButton;
                if (s == null) return;
    
                s.EnsureContextMenuIsValid();
                s.ContextMenu.PlacementRectangle = (Rect)e.NewValue;
            }
    
            /// <summary>
            /// HorizontalOffset Property changed callback, pass the value through to the buttons context menu
            /// </summary>
            private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                MyButton s = d as MyButton;
                if (s == null) return;
    
                s.EnsureContextMenuIsValid();
                s.ContextMenu.HorizontalOffset = (double)e.NewValue;
            }
    
            /// <summary>
            /// VerticalOffset Property changed callback, pass the value through to the buttons context menu
            /// </summary>
            private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                MyButton s = d as MyButton;
                if (s == null) return;
    
                s.EnsureContextMenuIsValid();
                s.ContextMenu.VerticalOffset = (double)e.NewValue;
            }
    
            /*
             * Helper Methods
             * 
            */
    
            /// <summary>
            /// Make sure the Context menu is not null
            /// </summary>
            private void EnsureContextMenuIsValid()
            {
                if (this.ContextMenu == null)
                {
                    this.ContextMenu = new System.Windows.Controls.ContextMenu();
                    this.ContextMenu.PlacementTarget = this;
                    this.ContextMenu.Placement = Placement;
    
                    this.ContextMenu.Opened += ((sender, routedEventArgs) => IsContextMenuOpen = true);
                    this.ContextMenu.Closed += ((sender, routedEventArgs) => IsContextMenuOpen = false);
                }
            }
    
            private void OnDropdown()
            {
                EnsureContextMenuIsValid();
                if (!this.ContextMenu.HasItems)
                    return;
    
                this.ContextMenu.IsOpen = !IsContextMenuOpen; // open it if closed, close it if open
            }
    
            /*
             * Events
             * 
            */
    
            /// <summary>
            /// Event Handler for the Drop Down Button's Click event
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Dropdown_Click(object sender, RoutedEventArgs e)
            {
                OnDropdown();
                e.Handled = true;
            }
        }
    }

    控件xaml

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:comm="clr-namespace:Controls">
    
        <Style x:Key="ButtonFocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle
                            Margin="3"
                            SnapsToDevicePixels="true"
                            Stroke="Transparent"
                            StrokeDashArray="1 2"
                            StrokeThickness="1" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="Button">
            <Setter Property="Foreground" Value="#D5D5D5" />
            <Setter Property="FontSize" Value="13" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Image
                            x:Name="image"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Source="{Binding Path=ImageSource, RelativeSource={RelativeSource AncestorType={x:Type comm:MyButton}}}" />
    
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="image" Property="Source" Value="{Binding Path=ImageSourceChange, RelativeSource={RelativeSource AncestorType={x:Type comm:MyButton}}}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="{x:Type comm:MyButton}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
            <Setter Property="FontSize" Value="13" />
            <Setter Property="Foreground" Value="#D5D5D5" />
            <Setter Property="FontFamily" Value="微软雅黑" />
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Padding" Value="0" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type comm:MyButton}">
                        <Border
                            x:Name="grid"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"
                            Background="Transparent"
                            CornerRadius="4">
    
                            <Button x:Name="PART_DropDown" />
                        </Border>
                        <ControlTemplate.Triggers>
    
    
                            <Trigger SourceName="PART_DropDown" Property="IsMouseOver" Value="true">
                                <Setter TargetName="PART_DropDown" Property="Opacity" Value="1" />
                                <Setter TargetName="grid" Property="Background" Value="Transparent" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="#ADADAD" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

    页面使用:

    <comm:MyButton
                        Width="38"
                        Height="40"
                        ImageSource="/control;component/Icons/picture2.png"
                        ImageSourceChange="/control;component/Icons/picture1.png">
    
                    </comm:MyButton>
  • 相关阅读:
    QT学习笔记
    局域网摄像头安装与调试
    从0开始搭建视觉检测智能车
    树莓派安装anaconda
    手把手教你搭建视觉检测智能车
    树莓派与Arduino串口通信实验
    树莓派设置关机重启键
    树莓派can通信
    树莓派GPIO使用笔记
    MySQL练习题
  • 原文地址:https://www.cnblogs.com/amwuau/p/7561570.html
Copyright © 2011-2022 走看看