WPF中如何自定義控件

WPF自定義控件簡化版:賬戶菜單按鈕(AccountButton)

我們以**“賬戶菜單按鈕”為例,用更清晰的架構實現一個支持標題顯示、漸變背景、選中狀態高亮**的自定義控件。以下是分步拆解:


一、控件核心功能

我們要做一個類似這樣的控件:

  • 外觀:一個圓形/圓角的小按鈕,中間顯示標題(如賬戶首字母)。
  • 背景:支持自定義漸變顏色(從顏色A到顏色B)。
  • 選中狀態:左側顯示一條高亮豎線(選中時可見,未選中時隱藏)。

二、控件架構設計(分3步)

步驟1:創建UserControl(控件容器)

WPF中自定義控件最常用的方式是繼承UserControl(用戶控件),它本質是一個可復用的UI容器,包含自己的XAML布局和后臺代碼。

步驟2:定義依賴屬性(暴露控件屬性)

為了讓控件能被外部配置(如修改標題、顏色、選中狀態),需要將這些屬性注冊為依賴屬性(DependencyProperty)。依賴屬性的優勢是支持數據綁定、樣式設置和動態更新。

步驟3:設計XAML布局(可視化界面)

在XAML中定義控件的UI結構,將依賴屬性綁定到具體的UI元素(如文本、背景顏色、可見性)。


三、完整代碼實現(簡化版)

1. 新建UserControl:AccountButton.xaml

XAML中定義控件的布局,核心是一個Button,內部包含兩個Border(高亮條和背景塊)。

<UserControl x:Class="MyApp.Controls.AccountButton"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Name="Root"  <!-- 給控件起別名,方便綁定 -->Width="30" Height="30">  <!-- 固定控件大小 --><!-- 根元素是一個按鈕 --><Button Style="{StaticResource BaseButtonStyle}">  <!-- 假設外部有基礎樣式 --><Grid><!-- 選中狀態高亮條(左側豎線) --><Border x:Name="ActiveIndicator"HorizontalAlignment="Left"Width="3"Background="#FF0078D7"  <!-- 藍色高亮 -->Visibility="Collapsed"  <!-- 默認隱藏 -->CornerRadius="0 2 2 0"/>  <!-- 右側圓角 --><!-- 背景塊(顯示漸變和標題) --><Border x:Name="ContentBorder"Width="25" Height="25"HorizontalAlignment="Center"VerticalAlignment="Center"CornerRadius="3">  <!-- 圓角 --><!-- 漸變背景 --><Border.Background><LinearGradientBrush StartPoint="0,0" EndPoint="1,1"><!-- 起始色綁定控件的GradientStart屬性 --><GradientStop Color="{Binding GradientStart, ElementName=Root}" Offset="0"/><!-- 結束色綁定控件的GradientEnd屬性 --><GradientStop Color="{Binding GradientEnd, ElementName=Root}" Offset="1"/></LinearGradientBrush></Border.Background><!-- 標題文本(綁定控件的Title屬性) --><TextBlock Text="{Binding Title, ElementName=Root}"VerticalAlignment="Center"HorizontalAlignment="Center"Foreground="White"FontWeight="Bold"/></Border></Grid></Button>
</UserControl>
2. 后臺代碼:AccountButton.xaml.cs

定義依賴屬性,并處理選中狀態的邏輯(例如:選中時顯示高亮條)。

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;namespace MyApp.Controls
{public partial class AccountButton : UserControl{public AccountButton(){InitializeComponent();}// ----------------------//  依賴屬性定義(共3個)// ----------------------// 1. 標題(如賬戶首字母)public string Title{get => (string)GetValue(TitleProperty);set => SetValue(TitleProperty, value);}public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title",              // 屬性名(必須與包裝器一致)typeof(string),       // 屬性類型typeof(AccountButton) // 控件類型(當前類));// 2. 漸變起始色public Color GradientStart{get => (Color)GetValue(GradientStartProperty);set => SetValue(GradientStartProperty, value);}public static readonly DependencyProperty GradientStartProperty = DependencyProperty.Register("GradientStart", typeof(Color), typeof(AccountButton));// 3. 漸變結束色public Color GradientEnd{get => (Color)GetValue(GradientEndProperty);set => SetValue(GradientEndProperty, value);}public static readonly DependencyProperty GradientEndProperty = DependencyProperty.Register("GradientEnd", typeof(Color), typeof(AccountButton));// 4. 選中狀態(新增:控制高亮條可見性)public bool IsActive{get => (bool)GetValue(IsActiveProperty);set => SetValue(IsActiveProperty, value);}public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register("IsActive", typeof(bool), typeof(AccountButton),new PropertyMetadata(false, OnIsActiveChanged) // 添加回調:狀態變化時觸發);// 當IsActive屬性變化時,更新高亮條可見性private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var button = d as AccountButton;if (button != null){// 根據IsActive的值顯示/隱藏高亮條button.ActiveIndicator.Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed;}}}
}

四、代碼關鍵點解釋(超簡單版)

1. 依賴屬性的作用
  • 外部可以通過TitleGradientStart等屬性直接配置控件(類似原生控件的WidthHeight)。
  • 示例:在主窗口中使用控件時,可以這樣寫:
    <controls:AccountButton Title="A" GradientStart="#FF0078D7" GradientEnd="#FF00B4D8" IsActive="True"/>
    
2. 選中狀態的自動更新

通過IsActivePropertyPropertyMetadata添加了OnIsActiveChanged回調函數。當IsActive的值變化時(如從False變為True),會自動觸發這個函數,更新高亮條的可見性。

3. XAML綁定的邏輯
  • ElementName=RootRoot是UserControl的x:Name,通過它可以直接訪問控件本身的屬性(如GradientStart)。
  • 漸變顏色直接綁定到GradientStartGradientEnd,當這兩個屬性的值變化時,背景會自動更新。

五、最終效果

  • 未選中時:顯示漸變背景和標題,左側高亮條隱藏。
  • 選中時:左側高亮條顯示(顏色固定為藍色),其他部分不變。

通過這種架構,你可以快速擴展控件功能(如添加點擊事件、修改高亮條顏色等),核心邏輯清晰易理解!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79722.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Deepseek+Xmind:秒速生成思維導圖與流程圖

deepseekxmind&#xff0c;快速生成思維導圖和流程圖 文章目錄 思維導圖deepseek筆記本 txt文件xmind 流程圖deepseekdraw.io 思維導圖 deepseek 筆記本 txt文件 將deep seek的東西復制到文本文件中&#xff0c;然后將txt文件拓展名改成md xmind 新建思維導圖----左上角三…

基于javaweb的SpringBoot愛游旅行平臺設計和實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

服務器機架的功能和重要性

服務器已經成為各個行業必不可少的網絡設備&#xff0c;而服務器機架則是數據中心和IT基礎設施中不可或缺的重要組成部分&#xff0c;服務器機架能夠為服務器和其他網絡設備提供物理支撐&#xff0c;同時還可以提供設備維護和管理等多種功能&#xff0c;本文就來介紹一下服務器…

游戲引擎學習第277天:稀疏實體系統

回顧并為今天定下基調 上次我們結束的時候&#xff0c;基本上已經控制住了跳躍的部分&#xff0c;達到了我想要的效果&#xff0c;現在我們主要是在等待一些新的藝術資源。因此&#xff0c;等新藝術資源到位后&#xff0c;我們可能會重新處理跳躍的部分&#xff0c;因為現在的…

阿克曼-幻宇機器人系列教程1- 實現上位機與下位機交互的兩種方式

1. 電腦與機器人通過SSH命令連接 1.1 將機器人上電 目的&#xff1a;將機器人變成熱點 目標&#xff1a;將電腦連接機器人網絡 熱點名稱&#xff1a;Huanyu-111 密碼&#xff1a;12345678 1.2 完成電腦與機器人之間的連接 實現&#xff1a;在電腦終端中執行命令通過SSH登錄…

Rust 中的 Pin 和 Unpin:內存安全與異步編程的守護者

在 Rust 的世界里&#xff0c;Pin 和 Unpin 是兩個看似不起眼、實則至關重要的概念。它們在內存安全和異步編程中扮演著關鍵角色&#xff0c;是 Rust 開發者必須掌握的知識。今天&#xff0c;就讓我們深入探討這兩個概念&#xff0c;看看它們是如何在 Rust 的生態系統中發揮作用…

如何界定合法收集數據?

首席數據官高鵬律師團隊 在當今數字化時代&#xff0c;數據的價值日益凸顯&#xff0c;而合法收集數據成為了企業、機構以及各類組織必須嚴守的關鍵準則。作為律師&#xff0c;深入理解并準確界定合法收集數據的范疇&#xff0c;對于保障各方權益、維護法律秩序至關重要。 一…

自動駕駛的“眼睛”:用Python構建智能障礙物檢測系統

自動駕駛的“眼睛”:用Python構建智能障礙物檢測系統 在自動駕駛技術日益成熟的今天,障礙物檢測系統成了汽車智能化不可或缺的部分。無論是高速公路上的突發狀況,還是城市街道中的行人與車輛,準確識別障礙物并及時反應,是保證行車安全的關鍵。 那么,我們如何用Python構…

19.Excel數據透視表:第2部分數據透視計算

一 日期組合 不想看具體是哪一天的收入&#xff0c;想看每個月的收入是多少&#xff0c;要對日期進行組合。 光標選中日期字段下的數據&#xff0c; 右鍵。 補充&#xff1a;第2種方法。 補充&#xff1a;可以同時選擇多個。 下面這個是錯誤的。 源數據里面有不同的年份&#x…

Eclipse 插件開發 6 右鍵菜單

Eclipse 插件開發 6 右鍵菜單 1 plugin.xml2 SampleHandler.java3 Activator.java 1 plugin.xml <?xml version"1.0" encoding"UTF-8"?> <?eclipse version"3.4"?> <plugin><!-- 定義命令 --><extension point&…

用vite腳手架建立 前端工程

? 參考 開始 | Vite 官方中文文檔 腳本 chcp 65001 echo 建立vite工程 set PRO_NAMEmy-vue-app call npm create vitelatest %PRO_NAME% --template vue cd ./%PRO_NAME%set NOW_PATH%cd% echo now_path %NOW_PATH% echo 點擊回車啟動vite工程&#xff0c;請訪問ht…

ESP32C3連接wifi

文章目錄 &#x1f527; 一、ESP32-C3 連接 Wi-Fi 的基本原理&#xff08;STA 模式&#xff09;? 二、完整代碼 注釋講解&#xff08;適配 ESP32-C3&#xff09;&#x1f4cc; 三、幾個關鍵點解釋&#x1f51a; 四、小結 &#x1f527; 一、ESP32-C3 連接 Wi-Fi 的基本原理&a…

LangSmith 基本使用教程

LangSmith 是一個強大的工具&#xff0c;可以幫助開發者追蹤、監控和分析語言模型應用程序的性能。下面我將介紹兩種基本的追蹤方式&#xff1a;追蹤 OpenAI 調用和追蹤整個應用程序。 1. 追蹤 OpenAI 調用 (Trace OpenAI calls) 這種方法主要用于追蹤對 OpenAI API 的調用&a…

Python基礎學習-Day23

目錄 基礎概念轉換器&#xff08;transformer&#xff09;估計器&#xff08;estimator&#xff09;管道&#xff08;pipeline&#xff09; 實例pipeline 基礎概念 pipeline在機器學習領域可以翻譯為“管道”&#xff0c;也可以翻譯為“流水線”&#xff0c;是機器學習中一個重…

相對論速度疊加公式與雙曲正切

復習下相對論速度疊加公式吧&#xff0c;物理&#xff0c;是不是很多人都忘了呀。假設速度為 u , v u,v u,v&#xff0c;那么疊加后的速度 w w w為&#xff1a; w u v 1 u v / c 2 w\frac{uv}{1uv/c^2} w1uv/c2uv? ??這個公式告訴我們&#xff0c;在一個速度為2/3光速的…

【前綴和】和為 K 的子數組(medium)

【前綴和】和為 K 的子數組 題目描述算法原理和細節問題代碼 題目描述 和為 K 的子數組 給定一個整數數組和一個整數 k &#xff0c;請找到該數組中和為 k 的連續子數組的個數。 示例 1&#xff1a; 輸入:nums [1,1,1], k 2 輸出: 2 解釋: 此題 [1,1] 與 [1,1] 為兩種不同的…

在Ubuntu服務器上部署Label Studio

一、拉取鏡像 docker pull heartexlabs/label-studio:latest 二、啟動容器 &#xff08;回到用戶目錄&#xff0c;例&#xff1a;輸入pwd&#xff0c;顯示 /home/<user>&#xff09; docker run -d --name label-studio -it -p 8081:8080 -v $(pwd)/mydata:/label-st…

MySQL 從入門到精通(三):日志管理詳解 —— 從排錯到恢復的核心利器

在 MySQL 數據庫的日常運維中&#xff0c;日志是定位問題、優化性能、數據恢復的核心工具。無論是排查服務器啟動異常&#xff0c;還是分析慢查詢瓶頸&#xff0c;亦或是通過二進制日志恢復誤刪數據&#xff0c;日志都扮演著 “數據庫黑匣子” 的角色。本文將深入解析 MySQL 的…

內存中的“BANK”

一、BANK的定義與物理結構 基本概念 BANK&#xff08;存儲體&#xff09; 是內存芯片內部的一個邏輯或物理分區&#xff0c;每個BANK由存儲單元陣列、地址解碼電路和緩沖器組成&#xff0c;用于分塊管理內存操作。 作用&#xff1a;通過并行操作減少訪問沖突&#xff0c;提升內…

機器學習——聚類算法練習題

一、 隨機創建不同二維數據集作為訓練集 &#xff0c;并結合k-means算法將其聚類 &#xff0c;你可以嘗試分別聚類不同數量的簇 &#xff0c;并觀察聚類 效果&#xff1a; 聚類參數n_cluster傳值不同 &#xff0c;得到的聚類結果不同 代碼展示&#xff1a; from sklearn.da…