首頁 > 軟體

.NET  Smobiler的複雜控制元件的由來與創造

2022-08-09 14:02:31

存在意義

Smobiler的複雜控制元件即利用自定義控制元件的方式組合控制元件,來使控制元件成為一個有機整體,裡面的控制元件可相互共同作業互動,並使其達到高可用。

在Smobiler中有許多基礎控制元件,TextBox文字輸入框控制元件可以呼叫輸入法在介面上自由輸入文字,Image圖片顯示控制元件可以在介面的任意位置顯示圖片,Label文字顯示控制元件可以在介面的任意位置顯示文字,Panel容器控制元件可存放其他控制元件。這些控制元件都是單獨的功能,而我們設計介面不可能只有使用一個控制元件,這時我們就需要組合相同與不同的控制元件來為我們服務。比如需要一個可顯示圖片並且圖片下方有文字註釋,並且當點選圖片時可觸發點選事件來跳轉另一個詳細的介紹介面,此時就需要使用Panel、Image、Label這些基礎的控制元件來組合使用。

那麼問題來了,當我同一個介面需要多次使用上面的Image組合控制元件,我是否需要一次又一次的手動組合控制元件呢?那我整個專案中不同的介面中又需要無數次的使用上面的Image組合控制元件,是否需要做無數次的相同工作?答案是:並不需要!Smobiler中有自定義控制元件的功能,顧名思義自定義控制元件就是使用者可根據自己的需要客製化自己的控制元件,自定義的控制元件可在工具箱中顯示。

當你在介面中需要運用多個相同的或者不同的控制元件,組合成一個各個控制元件相互關聯的大整體,並且實現了高複用。你可以設計方法,設計屬性,設計回撥事件,使用這些隨心所欲控制自己客製化的複雜控制元件。

可實現的場景

複雜控制元件即可滿足多種多樣複雜場景。

下面以一部分Smobiler官方推出的複雜控制元件為例:

AlbumView控制元件 —— 相簿控制元件,可設定縮圖點選後檢視原圖。使用者可使用該控制元件展示圖片。AlbumView控制元件主要由Panel、Image、PageView、Button、FontIcon基礎控制元件組合而成。

ImageButton控制元件 —— 含圖片的按鈕控制元件,可點選圖片觸發點選事件。
ImageButton控制元件主要由Panel、Image、Label基礎控制元件組合而成。

ListMenuView控制元件 —— 列表選單控制元件,可快速顯示列表資訊。
ListMenuView控制元件主要由Panel、Label、ImageButton、ImageEx組成。

Numeric控制元件 —— 數量控制元件。即可輸入數量,又可以點選按鈕增加或減少數量。Numeric控制元件主要由TextBox、FontIcon組成。

Poplist控制元件 —— 彈出列表選擇控制元件,可在選擇在介面彈出選擇框選擇相應的資訊。Poplist控制元件主要由Panel、Label、FontIcon、Button組成。

Radiogroup控制元件 —— 選擇控制元件,同樣功能不同樣式的選擇控制元件。RadioGroup控制元件主要由CheckBox、Label組成。

RatingBar控制元件 —— 評價控制元件,評分條控制元件可進行評價打分。RatingBar控制元件主要由Panel、FontIcon組成

TableView控制元件 —— 表格控制元件,可以表格的樣式顯示資訊。TableView控制元件主要由Panel、Button、Image、CheckBox、Label、TextBox組成。

ToolBar控制元件 —— 工具列控制元件,此控制元件可應用於底部點選顯示不同的介面。ToolBar控制元件主要由Panel、ImageEx、Label組成。

施展創造

樣式

下面我們就仿照Numeric控制元件的樣式不使用設計器以純程式碼的方式做一個複雜控制元件。
首先我們建立一個新的類取名為Numeric,如下圖:

之後程式碼中取名為數量控制元件。

/// <summary>
/// 數量控制元件
/// </summary>
//下面程式碼可使控制元件顯示在工具箱中。
[System.ComponentModel.ToolboxItem(true), System.ComponentModel.ToolboxItemFilter("Smobiler.Core.Controls")]
//取名,繼承MobileLayoutControl佈局控制元件、IMobileBindableControl資料繫結控制元件介面
public class Numeric : MobileLayoutControl, IMobileBindableControl
{   }

接下來我們就需要設計顯示Numeric了。Numeric控制元件時由Panel、FontIcon、TextBox組成,先建立下列控制元件。

    //Numeric中間的輸入框
    private TextBox txtValue;
    //Numeric左邊的減少的圖示
    private FontIcon fontMinus;
    //Numeric右邊的增加的圖示
    private FontIcon fontPlus;
    //使左邊圖示可點選
    private Panel Minus;
    //使右邊圖示可點選
    private Panel Plus;

主要控制元件建立完畢後,就需要設計這個基礎控制元件的顯示樣式了。

    /// <summary>
    /// 初始化Numeric類的一個新範例
    /// </summary>
    public Numeric()
    {
        //本介面使用相對佈局的方式,可按照自己順手方式。
        this.Layout = LayoutPosition.Relative;
        //最外層新增一個Panel裝所有的控制元件。
        Panel NPanel = new Panel();
        NPanel.Layout = LayoutPosition.Relative;
        //numeric需要橫向排列設定容器主軸方向為Row。
        NPanel.Direction = LayoutDirection.Row;
        //在相對佈局下使用Flex屬性撐滿介面
        NPanel.Flex = 1;
        NPanel.Width = 0;

        //設計左邊可點選的Panel樣式
        Minus = new Panel();
        Minus.Touchable = true;
        Minus.Layout = LayoutPosition.Relative;
        Minus.Flex = 1;
        Minus.Height = 0;
        Minus.Padding = new Padding(5, 0, 0, 0);
         Minus.BackColor = System.Drawing.Color.Transparent;

       //設計左邊的減少的圖示的樣式
       fontMinus = new FontIcon
        {
            FontName = FontIconName.FontAwesome,
            ResourceID = "minus-circle",
            ForeColor = System.Drawing.Color.DarkGray,
            Width = 0,
            Flex = 1
        };
       //設計完樣式之後把圖示放入Panel容器中,即右邊點選圖示部分即完成了。
       Minus.Controls.Add(fontMinus);

     //以同樣的方式設計右邊的點選圖示。
     .......
     .......
     Plus.Controls.Add(fontPlus);

     //設計中間的TextBox的樣式。
     txtValue = new TextBox();
     txtValue.Text = mValue.ToString();
     //相對佈局中設定txtValue的Flex為3,則對比Minus與Plus的1,表示txtValue為同一容器中大小佔據3的份額,Minus與Plus個佔據1.
     txtValue.Flex = 3;
     txtValue.Height = 0;
     txtValue.FontSize = 18;
     txtValue.KeyboardType = KeyboardType.Numeric;
     txtValue.HorizontalAlignment = HorizontalAlignment.Center;
     txtValue.BackColor = System.Drawing.Color.Transparent;

     //所有的樣式都設計完了,這時就可以組合在一起了。
     NPanel.Controls.AddRange(new MobileControl[] { Minus, txtValue, Plus });
        //自定義控制元件需要新增在SmobilerUserControl。
        var mControls = new MobileControlCollection();
        //註冊控制元件的集合
        base.RegisterControls(mControls);
        mControls.Add(NPanel);
    }

內部功能

此時與Numeric相同的樣式即實現了。但是相同的樣式並不能滿足需求,我們還需要實現裡面的邏輯,使之成為有功能的Numeric。

實現panel中的點選事件:

        Minus.Press += (obj, args) =>
        {
            if (string.IsNullOrEmpty(txtValue.Text.Trim()) == false)
            {
                decimal inputValue = 0;
                if (decimal.TryParse(txtValue.Text, out inputValue) == true)
                {
                    Value = inputValue - Variation;
                    initValue = Value;
                }
                else
                {
                    Value = Value;
                }
            }
            else{
                Value = mMinValue;
            }
        };

實現txtValue原本的事件:

 txtValue.TextChanged += (obj, args) =>
        {
         ......
        };
 txtValue.TouchEnter += (obj, args) =>
        {
         ......  
        };
        txtValue.TouchLeave += (obj, args) =>
        {
         ......    
        };

屬性

新增Numeric的屬性Value,可通過屬性設定顯示的值。

    private decimal mValue = 0;
    /// <summary>
    /// 設定控制元件顯示的預設值
    /// </summary>
    [Browsable(true), Category("Behavior"), DefaultValue(typeof(decimal), "0"), Description("顯示預設值")]
    public decimal Value
    {
        get
        {
            return mValue;
        }
        set
        {
            //新增判斷
            value = (decimal)Math.Round(value, mDecimals);

            if (this.Parent != null && this.Parent.Controls.Contains(this) == true && (value > mMaxValue))
                value = MaxValue;
            else if (this.Parent != null && this.Parent.Controls.Contains(this) == true && (value < mMinValue))
                value = MinValue;
            if (initValue==value)
            {
                TextChanged = false;
                mValue = value;
            }
           else if (mValue != value||TextChanged==true)
            {
                TextChanged = false;
                mValue = value;
                //if (ValueChanged != null)
                //ValueChanged.Invoke(this, new EventArgs());
            }
            //給txtValue賦值顯示。
            txtValue.Text = mValue.ToString("f" + Decimals);
        }
    }

方法

可以上面的方式新增不同的屬性。

也可新增控制元件的方法:

    /// <summary>
    /// 使控制元件獲取焦點。
    /// </summary>
    public void Focus()
    {
        txtValue.Focus();
    }
    /// <summary>
    /// 使控制元件失去焦點。
    /// </summary>
    public void Blur()
    {
        txtValue.Blur();
    }

繫結的屬性

另外可實現繫結的屬性,即可使用繫結的方式賦值

    private string mDisplayMember = "";
    /// <summary>
    /// 獲取和設定顯示繫結欄位。
    /// </summary>
    [Browsable(true), Category("Data"), Description("顯示繫結欄位"), DefaultValue("")]
    public string DisplayMember { get { return mDisplayMember; } set { mDisplayMember = value; } }
     .......
   [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public object BindDisplayValue
    {
        get
        {
            return Value;
        }
        set
        {
            if (value != null)
            {
                this.Value = decimal.Parse(value.ToString());
            }
        }
    }

這樣一個大致的Numeric的樣式與功能有已實現完畢,重新生成專案即可在工具箱中找到它了。

知識拓展

控制元件中還可以新增事件,當達到某些條件時觸發。
以Numeric中為例新增值改變時發生的事件。

    /// <summary>
    /// 值改變時發生
    /// </summary>
    [Description("值改變時發生")]
    public event EventHandler ValueChanged;

並且在Value值改動時使用該事件。

 if (ValueChanged != null) ValueChanged.Invoke(this, new EventArgs());

結語

Smobiler的複雜控制元件既豐富Smobiler的控制元件,又可讓使用者根據自己的需要客製化自己的控制元件提高了UI的多樣性,豐富使用者使用場景,其高可用又大大節約了使用者的開發時間。

到此這篇關於.NET  Smobiler的複雜控制元件的由來與創造的文章就介紹到這了,更多相關.NET Smobiler複雜控制元件內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com