wpf 兩個自定義控制項

来源:https://www.cnblogs.com/njit-77/archive/2019/11/10/11831475.html

wpf 兩個自定義控制項 一個是IP控制項,一個滑動條。先看下效果圖 IPControl 1、實際工作中有時需要設置IP信息,就想著做一個ip控制項。效果沒有window自帶的好,需要通過tab切換。但也能滿足使用。廢話不多說直接上代碼 IPControl.xaml IPControl.xaml.cs 2 ...


wpf 兩個自定義控制項

一個是IP控制項,一個滑動條。先看下效果圖

IPControl

1、實際工作中有時需要設置IP信息,就想著做一個ip控制項。效果沒有window自帶的好,需要通過tab切換。但也能滿足使用。廢話不多說直接上代碼

IPControl.xaml
<UserControl x:Class="WpfApp1.IPControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp1">

    <Viewbox>
        <Border>
            <DockPanel>
                <DockPanel.Resources>
                    <Style TargetType="{x:Type TextBox}">
                        <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        <Setter Property="VerticalContentAlignment" Value="Top"/>
                        <Setter Property="TextAlignment" Value="Center"/>
                        <Setter Property="BorderThickness" Value="0"/>
                        <Setter Property="HorizontalAlignment" Value="Left"/>
                        <Setter Property="VerticalAlignment" Value="Stretch"/>
                        <Setter Property="MaxLength" Value="3"/>
                        <Setter Property="Width" Value="30"/>
                        <Setter Property="Height" Value="25"/>
                    </Style>
                    <Style TargetType="{x:Type Label}">
                        <Setter Property="Content" Value="."/>
                    </Style>
                </DockPanel.Resources>
                <TextBox TabIndex="1" GotFocus="TextBoxGotFocus" Text="{Binding Path=FirstIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
                <Label/>
                <TextBox TabIndex="2" GotFocus="TextBoxGotFocus" Text="{Binding Path=SecondIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
                <Label/>
                <TextBox TabIndex="3" GotFocus="TextBoxGotFocus" Text="{Binding Path=ThirdIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
                <Label/>
                <TextBox TabIndex="4" GotFocus="TextBoxGotFocus" Text="{Binding Path=ForthIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
            </DockPanel>
        </Border>
    </Viewbox>
</UserControl>
IPControl.xaml.cs
    public partial class IPControl : UserControl
    {
        public IPControl()
        {
            InitializeComponent();
        }


        #region  DependencyProperty

        public static readonly DependencyProperty IPAddressProperty =
            DependencyProperty.Register("IPAddress", typeof(string), typeof(IPControl), new PropertyMetadata(defaultIP, (d, e) =>
            {
                if (d is IPControl control)
                {
                    control.UpdateParts(control);
                }
            }));

        public string IPAddress
        {
            get { return (string)GetValue(IPAddressProperty); }
            set { SetValue(IPAddressProperty, value); }
        }

        #endregion


        #region Static Field

        private static readonly string defaultIP = "127.0.0.1";

        #endregion


        #region Field

        private string firstIPValue;
        private string secondIPValue;
        private string thirdIPValue;
        private string forthIPValue;

        #endregion


        #region Property

        public string FirstIPValue
        {
            get { return firstIPValue; }
            set
            {
                if (firstIPValue != value)
                {
                    UpdateIPText(value, 1, ref firstIPValue);
                }
            }
        }

        public string SecondIPValue
        {
            get { return secondIPValue; }
            set
            {
                if (secondIPValue != value)
                {
                    UpdateIPText(value, 0, ref secondIPValue);
                }
            }
        }

        public string ThirdIPValue
        {
            get { return thirdIPValue; }
            set
            {
                if (thirdIPValue != value)
                {
                    UpdateIPText(value, 0, ref thirdIPValue);
                }
            }
        }

        public string ForthIPValue
        {
            get { return forthIPValue; }
            set
            {
                if (forthIPValue != value)
                {
                    UpdateIPText(value, 0, ref forthIPValue);
                }
            }
        }

        #endregion


        #region Private Method

        private void TextBoxGotFocus(object sender, RoutedEventArgs e)
        {
            InputMethod.Current.ImeState = InputMethodState.Off;
            TextBox tb = sender as TextBox;
            if (tb.Text.Length != 0)
            {
                tb.SelectAll();
            }
        }

        private void UpdateIPText(string oldvalue, int minValue, ref string newValue)
        {
            int.TryParse(oldvalue, out int iValue);
            if (iValue < minValue)
            {
                iValue = minValue;
            }
            if (iValue > 255)
            {
                iValue = 255;
            }
            newValue = iValue.ToString();
            IPAddress = GetIPAddress();
        }

        private string GetIPAddress()
        {
            string str = "";
            if (firstIPValue != null && firstIPValue.Length > 0)
            {
                str += firstIPValue + ".";
            }
            else
            {
                str += "0.";
            }
            if (secondIPValue != null && secondIPValue.Length > 0)
            {
                str += secondIPValue + ".";
            }
            else
            {
                str += "0.";
            }
            if (thirdIPValue != null && thirdIPValue.Length > 0)
            {
                str += thirdIPValue + ".";
            }
            else
            {
                str += "0.";
            }
            if (forthIPValue != null && forthIPValue.Length > 0)
            {
                str += forthIPValue;
            }
            else
            {
                str += "0";
            }
            return str;
        }

        private void UpdateParts(IPControl control)
        {
            if (control.IPAddress == null)
            {
                control.IPAddress = defaultIP;
            }
            string[] parts = control.IPAddress.Split('.');
            if (parts.Length == 4)
            {
                control.FirstIPValue = parts[0];
                control.SecondIPValue = parts[1];
                control.ThirdIPValue = parts[2];
                control.ForthIPValue = parts[3];
            }
        }

        #endregion

    }

2、控制項有4個TextBox、4個Label組成。TextBox顯示IP值,Label顯示IP數據的“.”。

TextBox綁定依賴屬性,設置TabIndex參數,通過Tab按鍵切換到下一個TextBox。每個TextBox最多輸入3位

LightControl

1、前段時間,領導緊急安排一個工作。做一個測試燈光的小軟體。與負責燈光同事溝通得知,光源板可同時控制24路燈。也就是說軟體界面上需要有24個ScrollBar用來表示燈光亮度,24個Label顯示名稱。這要是一個一個控制項加太慢了,沒法做一個自定義空間,可設置顯示名稱,通過滑動條或者直接設置參數,改變亮度。於是需要一個Label、一個ScrollBar、一個TextBox與ScrollBar關聯。

LightControl.xaml
<UserControl x:Class="WpfApp1.LightControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp1">

    <Viewbox>
        <Border>
            <DockPanel>
                <Label Content="{Binding Path=LabelContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LightControl}}}"
                       FontSize="17" Width="80" VerticalContentAlignment="Center"/>
                <ScrollBar Value="{Binding Path=LightValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LightControl}}}"
                           Orientation="Horizontal" Height="40" Width="200" Maximum="100" SmallChange="1"/>
                <TextBox Text="{Binding Path=LightValue, StringFormat={}{0:F4}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LightControl}}, UpdateSourceTrigger=PropertyChanged}"
                         FontSize="17" Width="80" VerticalContentAlignment="Center"/>
            </DockPanel>
        </Border>
    </Viewbox>
</UserControl>
LightControl.xaml.cs
    public partial class LightControl : UserControl
    {
        public LightControl()
        {
            InitializeComponent();
        }


        #region  DependencyProperty

        public static readonly DependencyProperty LabelContentProperty =
            DependencyProperty.Register("LabelContent", typeof(string), typeof(LightControl), new PropertyMetadata("燈光"));

        public string LabelContent
        {
            get { return (string)GetValue(LabelContentProperty); }
            set { SetValue(LabelContentProperty, value); }
        }


        public static readonly DependencyProperty LightValueProperty =
            DependencyProperty.Register("LightValue", typeof(double), typeof(LightControl), new PropertyMetadata(1.0));

        public double LightValue
        {
            get { return (double)GetValue(LightValueProperty); }
            set { SetValue(LightValueProperty, value); }
        }

        #endregion


    }

2、Label顯示名稱通過依賴屬性由外接傳入。

3、ScrollBar的Value屬性與TextBox的Text屬性綁定同一個依賴屬性,可傳遞到調用者,同時TextBox顯示信息設置保留小數點4位。

工作中有時需要自己做一些自定義控制項,用來滿足不同場景的需求。兩個小控制項,比較簡單,希望此文能提供一些思路給你。


您的分享是我們最大的動力!

更多相關文章
  • 你可能想創建一個在應用的任何地方都可以訪問的函數,這個教程將幫你實現 👏 很多教程都會說,你在 composer.json 這個文件中通過添加一個自動載入的文件,就可以實現這個需求。但我認為這不是一個好的方式,當你在 helpers.php 文件中添加了更多的函數時,可讀性將變得很差。 下麵我將介 ...
  • 在說正題之前先解釋一下交換機模式是個籠統的稱呼,它不是一個單獨的模式(包括了訂閱模式,路由模式和主題模式),交換機模式是一個比較常用的模式,主要是為了實現數據的同步。 首先,說一下訂閱模式,就和字面上的意思差不多主要就是一個生產者,多個消費者,同一個消息被多個消費者獲取,先看一下官網的圖示 整體執行 ...
  • 當創建隊列jobs、監聽器或訂閱伺服器以推送到隊列中時,您可能會開始認為,一旦分派,隊列工作器決定如何處理您的邏輯就完全由您自己決定了。 嗯……並不是說你不能從作業內部與隊列工作器交互,但是通常情況下,哪怕你做了,也是沒必要的。 這個神奇的騷操作的出現是因為“InteractsWithQueue”這 ...
  • 環境:MacOS 10.13 MAMAP Prophp 7.0.33 + xdebugVisual Studio Code前言我所理解的 POP Chain:利用魔術方法並巧妙構造特殊屬性調用一系列函數或類方法以執行某種敏感操作的調用堆棧反序列化常用魔法函數前言我所理解的 POP Chain:利用魔 ...
  • 【ASP.NET Core學習】在ASP.NET Core 種使用Entity Framework Core介紹,包括如何添加Entity Framwork Core,創建模型和遷移到資料庫,查詢數據,保存數據,使用事務,處理併發衝突 ...
  • [toc] 前言 在之前已經提到過,公用類庫Util已經開源,目的一是為了簡化開發的工作量,畢竟有些常規的功能類庫重覆率還是挺高的,二是為了一起探討學習軟體開發,用的人越多問題也就會越多,解決的問題越多功能也就越完善, 倉庫地址: "April.Util_github" , "April.Util_ ...
  • 在面對對象編程中,類的三大特性分別為封裝,繼承,多態。其中多態的具體實現,依賴於三個方法,也就是虛方法,抽象類和介面。 多態的具體作用是什麼呢?或者說多態的存在有什麼意義呢?多態的存在有效的降低了程式的耦合度,在使用的時候,不僅可以表現大家都有的共性,還能在必要的時候突出一些特殊的的個性。 那麼如何 ...
  • 近期和幾位做嵌入式開發的朋友閑聊過程中,一位朋友抱怨到:這C#太難用了,我想在N個窗體(或者是N個用戶組件之間)傳遞值都搞不定,非得要定義一個全局變數來存儲,然後用定時器來刷新值,太Low了。我急切的回答道:這很簡單,不就是委托的事嘛。那你來一個示例啊:朋友道。此為這篇博客的起因,所以此篇博客對於有 ...
一周排行
  • 在園子裡面有很多關於各種技術細節的研究文章,都是比較牛逼的框架研究;但是一直沒有看到關於怎麼樣提高開發效率的文章,大多提高開發效率的文章都是關於自動化等方面的輔助工具類型的,而不是開發中的一些小技巧;今天從編碼規範、編碼技巧、開發思想、設計模式等各方面的經驗來分享如何提高開發效率。 ...
  • 前言 隨著近些年微服務的流行,有越來越多的開發者和團隊所採納和使用,它的確提供了很多的優勢也解決了很多的問題,但是我們也知道也並不是銀彈,提供優勢的同時它也給我們的開發人員和團隊也帶來了很多的挑戰。 為了迎接或者採用這些新技術,開發團隊需要更加註重一些流程或工具的使用,這樣才能更好的適應這些新技術所 ...
  • 本文是本系列的完結篇。本系列前面的文章: 邏輯式編程語言極簡實現(使用C#) - 1. 邏輯式編程語言介紹 邏輯式編程語言極簡實現(使用C#) - 2. 一道邏輯題:誰是凶手 邏輯式編程語言極簡實現(使用C#) - 3. 運行原理 下午,吃飽飯的老明和小皮,各拿著一杯剛買的咖啡回到會議室,開始了邏輯 ...
  • 微服務之間的通信之gRPC 介紹 gRPC是一種與語言無關的高性能遠程過程調用 (RPC) 框架,gRPC是Google發佈的基於HTTP 2.0傳輸層協議承載的高性能開源軟體框架,提供了支持多種編程語言的、對網路設備進行配置和納管的方法。由於是開源框架,通信的雙方可以進行二次開發,所以客戶端和服務 ...
  • 一、TLS 線程本地存儲(Thread Local Storage),字面意思就是專屬某個線程的存儲空間。變數大體上分為全局變數和局部變數,一個進程中的所有線程共用地址空間,這個地址空間被劃分為幾個固有的區域,比如堆棧區,全局變數區等,全局變數存儲在全局變數區,虛擬地址固定;局部變數存儲在堆棧區,虛... ...
  • private:私有成員,在類的內部才可以訪問。 protected:保護成員,該類內部和繼承類中可以訪問。 public:公共成員,完全公開,沒有訪問限制。 internal:當前程式集內可以訪問。 ...
  • 前言 上一篇【.Net Core微服務入門全紀錄(六)——EventBus-事件匯流排】中使用CAP完成了一個簡單的Eventbus,實現了服務之間的解耦和非同步調用,並且做到數據的最終一致性。這一篇將使用IdentityServer4來搭建一個鑒權中心,來完成授權認證相關的功能。 IdentitySe ...
  • using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System. ...
  • 從今天起,我將製作一個電影推薦項目,在此寫下博客,記錄每天的成果。 其實,從我發佈 C# 爬取貓眼電影數據 這篇博客後, 我就已經開始製作電影推薦項目了,今天寫下這篇博客,也是因為項目進度已經完成50%了,我就想在這一階段停一下,回顧之前學到的知識。 一、主要為手機端 考慮到項目要有實用性,我選擇了 ...
  • 一、實現Runnable介面 public class RunnableDemo implements Runnable { public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.print ...