如何使用属性创建自定义控件

时间:2017-11-29 11:28:29

标签: xamarin xamarin.forms

我需要创建一个带属性的自定义控件。

这是我的自定义控件:

worker_processes  2; 

events {    
     worker_connections 2000;
} 

http {

include       mime.types;
default_type  application/octet-stream;
client_max_body_size 50M;
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$gzip_ratio" "$http_x_forwarded_for"';

access_log  logs/access.log main;
error_log   logs/error.log;

sendfile        on;

keepalive_timeout  65;

server {
    client_max_body_size 50M;
    listen       80;
    server_name  localhost;

    include drop.conf;


    # gzip compression configurations       
    gzip on;
    gzip_disable "msie6";
    gzip_comp_level 6;
    gzip_min_length 1100;
    gzip_buffers 16 8k;
    gzip_proxied any;
    gzip_types text/plain text/css text/js text/xml text/javascript application/javascript application/x-javascript application/json application/xml application/rss+xml image/svg+xml;


    # Expire rules for static content

    # cache.appcache, your document html and data
    location ~* \.(?:manifest|appcache|html?|xml|json)$ {
      expires -1;
    }

    # Feed
    location ~* \.(?:rss|atom)$ {
      expires 1h;
      add_header Cache-Control "public";
    }

    # Media: images, icons, video, audio, HTC
    location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff|woff2|map)$ {
      expires -1;
      access_log off;
      #add_header Cache-Control "public";
    }

    # CSS and Javascript
    location ~* \.(?:css|js|ttf)$ {
      expires -1;
      access_log off;
      #add_header Cache-Control "public";
    }

    #charset koi8-r;
    root   html/valeroo;
    index  index.html index.htm index.php;
    access_log  logs/valeroo.access.log;
    error_log   logs/valeroo.error.log;



    # why we need it? what it does? analyse it first
    if ($request_uri ~* "^(.*/)index\.php$") {
        return 301 $1;
    }

    location / {
        client_max_body_size 50M;
        try_files $uri $uri/ /index.php$is_args$args;
        if ($request_uri ~* "^(.*/)index\.php(/?)(.*)") {
            return 301 $1$3;
        }
        # turns-off auto indexing
        autoindex off;
    }

    # Remove trailing slash.
    if (!-d $request_filename) {
        rewrite ^/(.+)/$ /$1 permanent;
    }

    #location /staging/ {
        #client_max_body_size 50M;
        #root   html\valeroo\staging; 
        #index  index.html index.htm index.php;
        #try_files $uri $uri/ /staging/index.php$is_args$args;

        # turns-off auto indexing
        #autoindex off;
    #}

    location @missing {
        rewrite ^ $scheme://$host/index.php permanent;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {                 
        include         fastcgi_params;
        fastcgi_index   index.php;
        fastcgi_read_timeout 600;
        fastcgi_pass    127.0.0.1:9071;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;

    }
    location ~* (.*\.pdf) {
        types { application/octet-stream .pdf; }
        default_type application/octet-stream;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one

    location ~ /\.ht {
      deny  all;
    }

    #blocking the project folders   
    location /app/{deny all;}
    location /bootstrap/{deny all;}
    location /build/{deny all;}
    location /config/{deny all;}
    location /env/{deny all;}
    location /resources/{deny all;}
    location /storage/{deny all;}
    location /tests/{deny all;}
    location /vendor/{deny all;}        
}

但是当我尝试在xaml中使用它时说:“没有默认构造函数查找”,如果我创建默认构造函数,则调用this而不是使用参数调用构造函数。

这是我的xaml:

public class ExpandableStackLayout : StackLayout
{
    public String Title{get;set;}

    public ContentView View { set; get; }

    public String Image{set;get;}


    public ExpandableStackLayout(string title, string image, ContentView view)
    {
        Title = title;
        Image = image;
        View = view;
    }
}

更新

我尝试了你的提示,我有其他问题:

<control:ExpandableStackLayout Title="Title" Image="imag.png">
            <control:ExpandableStackLayout.View>
                <ContentView>
                    <OtherView/>
                </ContentView>
            </control:ExpandableStackLayout.View>
        </control:ExpandableStackLayout>

3 个答案:

答案 0 :(得分:4)

无需创建构造函数。以下是如何实现Title和Image属性的解决方案。

public class ExpandableStackLayout : StackLayout
{
    public static readonly BindableProperty TitleProperty =
        BindableProperty.Create<ExpandableStackLayout, string>(p => p.Title, string.Empty, BindingMode.TwoWay);

    public string Title
    {
        get { return (string)base.GetValue(TitleProperty); }
        set { base.SetValue(TitleProperty, value); }
    }

    public static readonly BindableProperty ImageProperty =
        BindableProperty.Create<ExpandableStackLayout, string>(p => p.Image, string.Empty, BindingMode.TwoWay);

    public string Image
    {
        get { return (string)base.GetValue(ImageProperty); }
        set { base.SetValue(ImageProperty, value); }
    }
}

我不知道你想用View实现什么。首先,我建议您学习these controlsStacklayout implementation

答案 1 :(得分:3)

对于从.xaml到.cs代码的变量绑定,您应该使用Bindable Properties。

您的.cs文件应如下所示

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ExpandableStackLayout  : StackLayout
{
    public ExpandableStackLayout ()
    {
        this.InitializeComponent();
    }

    public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(ExpandableStackLayout), string.Empty);

    public string Title
    {
        get
        {
            return (string)GetValue(TitleProperty);
        }
        set
        {
            SetValue(TitleProperty, value);
        }
    }
}

答案 2 :(得分:1)

自定义视图的属性不应该通过构造函数设置。实现自定义视图属性的方法是Bindable Properties

基本上你必须创建两件事来创建一个完全成熟的可绑定属性:

  • A public static BindableProperty
  • 分别在显式getter和setter中获取和设置BindableProperty的C#属性

我将使用Title属性作为示例来解释它。首先创建一个简单的自动属性(C#属性和BindableProperty是相互依赖的)

public string Title { get; set; }

在第二步中,您可以创建BindableProperty

public static readonly BindableProperty TitleProperty 
    = BindableProperty.Create(nameof(Title), typeof(string), typeof(ExpandableStackLayout)); 

TitleProperty是一个命名约定,可以从您的XAML访问该属性Title

最后一步是通过TitleProperty

访问Title的值
public string Title
{
    get => (string)GetValue(TitleProperty);
    set => SetValue(TitleProperty, value);
}

这简化了访问TitleProperty