zoukankan      html  css  js  c++  java
  • WPF简单的User Control

    很早以前就接触了WPF,可是一直没怎么仔细研究过。最近做Windows Phone时又开始接触相关内容。在一个功能中,需要显示一些保存的城市列表,决定用自定义控件做。因为以前没仔细学习WPF,现在就趁着用到看了点。

    =================以下段落转自网络并做出了修改====================

    我们为控件(或者任何一个WPF 类)添加的依赖属性都是"公开的","静态的","只读的",其命名方式是"属性名+Property",这是依赖属性一成不变的
    书写方式.对于依赖属性的注册可以在声明该属性时就调用DependencyProperty.Register()方法注册,也可以在其静态构造方法中注册.上面的
    DependencyProperty.Register 方法的几个参数分别是:属性名(该属性名与声明的依赖属性名称"XXXProperty"相比仅仅是少了"Property"
    后缀,其它完全一样,否则在运行时会报异常),属性的数据类型,属性的拥有者的类型,元数据.
    关于参数中传递的元数据: 如果是普通的类则应该传递PropertyMetadata, 如果是FrameworkElement 则可以传递
    FrameworkPropertyMetadata, 其中FrameworkPropertyMetadata 中可以制定一些标记表明该属性发生变化时控件应该做出什么反应,比如某
    属性的变化会影响到该控件的绘制, 那么就应该像这样书写该属性的元数据: new FrameworkPropertyMetadata(defauleValue,
    FrameworkPropertyMetadataOptions.AffectsRender);这样当该属性发生变化时系统会考虑重绘该控件.另外元数据中还保护很多内容,比
    如默认值,数据验证,数据变化时的回调函数,是否参与属性"继承"等.
    然后,我们将该依赖属性包装成普通属性:
     1 [Description("获取或设置当前城市")]
     2 [Category("Common Properties")]
     3 public string City
     4 {
     5 get
     6 {
     7 return (string)this.GetValue(CityProperty);
     8 } set
     9 {
    10 this.SetValue(CityProperty, value);
    11 }
    12 }


    GetValue 和SetValue 方法来自于DependencyObject 类,其用于获取或设置类的某属性值.
    注意:在将依赖属性包装成普通属性时,在get 和set 块中除了按部就班的调用GetValue 和SetValue 方法外,不要进行任何其它的操作.下面的代码
    是不恰当的:

     1         [Description("获取或设置当前气温")]
     2         [Category("Common Properties")]
     3         public string Temperature
     4         {
     5             get
     6             {
     7                 return (string)this.GetValue(TemperatureProperty);
     8             }
     9             set
    10             {
    11                 this.SetValue(TemperatureProperty, value);
    12                 this.OnTimeUpdated(value);//Error
    13             }
    14         }


    在以前这或许是很多人的惯用写法,但在WPF 中,这样的写法存在潜在的错误,原因如下:我们知道继承于DependencyObject 的类拥有GetValue 和
    SetValue 方法来获取或设置属性值,那为什么我们不直接使用该方法来获取或设置属性值,而要将其包装成普通的.NET 属性呢,事实上在这里两种方
    式都是可以的,只不过包装成普通的.NET 属性更符合.NET 开发人员的习惯,使用GetValue 和SetValue 更像JAVA 开发人员的习惯,但XAML 在执
    行时似乎于JAVA 开发人员一样,其不会调用.NET 属性而是直接使用GetValue 或SetValue 方法,这样一来,我们写在get 块和set 块中的其它代
    码根本不会被XAML 执行到.所以说,就上面的Time 属性而言,C#(或其它)对该属性的调用不会出现任何问题,但该属性被用在XAML 中时(比如在XAML
    对该属性进行数据绑定等),其set 块中的this.OnTimeUpdated(value);语句不会被执行到.
    那么,当Time 属性发生变化时的确需要调用this.OnTimeUpdated(value); 语句(因为该语句会引发时间被更新了的事件),还是在传递的依赖属性
    元数据做文章:
    new FrameworkPropertyMetadata(DateTime.Now,new PropertyChangedCallback(TimePropertyChangedCallback)), 我们为属性
    的变化指定了一个回调函数,当该属性变化时该回调函数就会被执行

    ==================页面设计======================

    View Code
     1     <Grid Name="gd" Height="200" Width="200">
     2         <Grid.RowDefinitions>
     3             <RowDefinition Height="*"/>
     4             <RowDefinition Height="*"/>
     5         </Grid.RowDefinitions>
     6         <Grid.ColumnDefinitions>
     7             <ColumnDefinition Width="*"/>
     8             <ColumnDefinition Width="*"/>
     9         </Grid.ColumnDefinitions>
    10 
    11         <TextBlock Name="txtCity" Grid.Row="0" Grid.Column="0" FontSize="40" FontFamily="Microsoft YaHei">
    12             <TextBlock.BitmapEffect >
    13                 <OuterGlowBitmapEffect Opacity="0.6"></OuterGlowBitmapEffect>
    14             </TextBlock.BitmapEffect>
    15         </TextBlock>
    16         <TextBlock Name="txtTemp" Grid.Row="1" Grid.Column="0" FontSize="40" FontFamily="Microsoft YaHei">
    17             <TextBlock.BitmapEffect >
    18                 <OuterGlowBitmapEffect Opacity="0.6"></OuterGlowBitmapEffect>
    19             </TextBlock.BitmapEffect>
    20         </TextBlock>
    21         <Image Grid.Row="0" Grid.Column="1" Name="img" ></Image>
    22     </Grid>

    ==================后台代码======================

    View Code
    namespace userC
    {
        /// <summary>
        /// Interaction logic for UserControl1.xaml
        /// </summary>
        public partial class UserControl1 : UserControl
        {
    
            #region DP
            public string City
            {
                get
                {
                    return (string)this.GetValue(CityProperty);
                }
                set
                {
                    SetValue(CityProperty, value);
                }
            }
    
    
    
            public static DependencyProperty CityProperty = DependencyProperty.Register("City", typeof(string), typeof(UserControl1), new PropertyMetadata("长春"));
    
            public string Temperature
            {
                get
                {
                    return (string)this.GetValue(TemperatureProperty);
                }
                set
                {
                    SetValue(TemperatureProperty, value);
                }
            }
    
            public static DependencyProperty TemperatureProperty = DependencyProperty.Register("Temperature", typeof(string), typeof(UserControl1), new PropertyMetadata("20"));
    
            public string ImagePath
            {
                get
                {
                    return (string)this.GetValue(ImagePathProperty);
                }
                set
                {
                    SetValue(ImagePathProperty, value);
                }
            }
    
            public static DependencyProperty ImagePathProperty = DependencyProperty.Register("ImagePath", typeof(string), typeof(UserControl1), new PropertyMetadata("null"));
    
            public Brush Background
            {
                get
                {
                    return (Brush)this.GetValue(BackgroundProperty);
                }
                set
                {
                    SetValue(BackgroundProperty, value);
                }
            }
    
            public static DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(UserControl1), new PropertyMetadata(Brushes.Cyan));
    
            #endregion
    
    
            public UserControl1()
            {
                InitializeComponent();
            }
    
            protected override void OnInitialized(EventArgs e)
            {
                base.OnInitialized(e);
    
                Binding cityBinding = new Binding();
                cityBinding.Source = this;
                cityBinding.Path = new PropertyPath(UserControl1.CityProperty);
                this.txtCity.SetBinding(TextBlock.TextProperty, cityBinding);
    
                Binding temBinding = new Binding();
                temBinding.Source = this;
                temBinding.Path = new PropertyPath(UserControl1.TemperatureProperty);
                this.txtTemp.SetBinding(TextBlock.TextProperty, temBinding);
    
                Binding imgBinding = new Binding();
                imgBinding.Source = this;
                imgBinding.Path = new PropertyPath(UserControl1.ImagePathProperty);
                this.img.SetBinding(Image.SourceProperty, imgBinding);
    
                Binding bgBinding = new Binding();
                bgBinding.Source = this;
                bgBinding.Path = new PropertyPath(UserControl1.BackgroundProperty);
                this.gd.SetBinding(Grid.BackgroundProperty, bgBinding);
            }
        }
    }

    ==================前台调用======================

    先引用User Control工程

    using userC;

    然后在WrapPanel里面添加自定义控件

    1   public MainWindow()
    2         {
    3             InitializeComponent();
    4 
    5             wp.Children.Add(new UserControl1 { City = "宿迁", Temperature = "25", ImagePath = "/usercontrol;component/晴D.png", Background = Brushes.Pink });
    6             wp.Children.Add(new UserControl1 { City = "长春", Temperature = "10", ImagePath = "/usercontrol;component/多云D.png", Background = Brushes.RosyBrown });
    7             wp.Children.Add(new UserControl1 { City = "北京", Temperature = "15", ImagePath = "/usercontrol;component/冻雨N.png" });
    8         }

    工程源码

  • 相关阅读:
    Jmeter+Ant+Jenkins搭建持续集成的接口测试(推荐 Mark)
    配置sonar、jenkins进行持续审查
    查看端口占用
    CentOS 6.5系统上安装SVN服务器端的方法及目录访问权限配置(转总结)
    Windows批处理 调用程序后 不等待子进程 父进程继续执行命令
    Jmeter笔记:响应断言详解
    Ubuntu 16.04常用快捷键
    如何永久激活(破解) IntelliJ IDEA 2018.2
    Cobbler自动化部署
    Typora使用说明(记录总结)
  • 原文地址:https://www.cnblogs.com/NailClipper/p/2691527.html
Copyright © 2011-2022 走看看