欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WPF自定義控件綁定數(shù)據(jù)對(duì)象的最佳實(shí)踐

 更新時(shí)間:2025年09月22日 08:59:01   作者:code bean  
這篇文章主要介紹了WPF自定義控件數(shù)據(jù)綁定最佳實(shí)踐:直接使用DataContext簡(jiǎn)單但易沖突,依賴(lài)屬性更清晰且適合列表場(chǎng)景,推薦在需回寫(xiě)或列表使用時(shí)采用依賴(lài)屬性模式,需要的朋友可以參考下

引言

在 WPF 中開(kāi)發(fā)自定義控件時(shí),如何優(yōu)雅地綁定數(shù)據(jù)對(duì)象,是一個(gè)經(jīng)常遇到的問(wèn)題。最近在實(shí)現(xiàn)一個(gè)自定義的 ImageView 控件時(shí),我遇到了一個(gè)典型場(chǎng)景:

  • 控件內(nèi)部需要使用第三方控件 HSmartWindowControlWPF 來(lái)顯示圖像;
  • 控件需要和業(yè)務(wù)對(duì)象 GraphicInfo 綁定,并且要把自身引用回寫(xiě)到 GraphicInfo.View;
  • 控件還要支持在 ItemList(例如 ListBox)中批量使用。

本文就以這個(gè)案例為例,來(lái)總結(jié)下最佳實(shí)踐。

1. 直接使用 DataContext 的問(wèn)題

最初的寫(xiě)法是這樣的:

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    var hSmart = (HSmartWindowControlWPF)GetTemplateChild("PART_hSmart");
    hSmart.Loaded += Hsmart_Loaded;
    hSmart.HMouseMove += HSmart_HMouseMove;

    if (DataContext is GraphicInfo info)
    {
        info.View = this; // 子類(lèi)控件回寫(xiě)到數(shù)據(jù)對(duì)象
    }
}

XAML 里:

<local:ImageView DataContext="{Binding MyGraphic}" />

這種方式雖然能用,但有幾個(gè)問(wèn)題:

  • 控件內(nèi)部和外部公用了同一個(gè) DataContext,如果控件內(nèi)部還需要 MVVM 綁定,會(huì)和外部沖突。
  • ItemList 中使用時(shí)不夠直觀,容易出錯(cuò)。

2. 定義依賴(lài)屬性(推薦)

更好的做法是為控件定義一個(gè)依賴(lài)屬性,例如 Graphic

public class ImageView : Control
{
    static ImageView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageView),
            new FrameworkPropertyMetadata(typeof(ImageView)));
    }

    // 定義依賴(lài)屬性
    public GraphicInfo Graphic
    {
        get => (GraphicInfo)GetValue(GraphicProperty);
        set => SetValue(GraphicProperty, value);
    }

    public static readonly DependencyProperty GraphicProperty =
        DependencyProperty.Register(nameof(Graphic), typeof(GraphicInfo), typeof(ImageView),
            new PropertyMetadata(null, OnGraphicChanged));

    private static void OnGraphicChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is ImageView view && e.NewValue is GraphicInfo info)
        {
            info.View = view; // 在綁定時(shí)回寫(xiě)
        }
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        var hSmart = (HSmartWindowControlWPF)GetTemplateChild("PART_hSmart");

        if (hSmart != null)
        {
            hSmart.Loaded += Hsmart_Loaded;
            hSmart.HMouseMove += HSmart_HMouseMove;
        }
    }

    private void Hsmart_Loaded(object sender, RoutedEventArgs e) { }
    private void HSmart_HMouseMove(object sender, HMouseEventArgs e) { }
}

這樣,控件就有了一個(gè)獨(dú)立的 Graphic 屬性,外部綁定時(shí)可以很清晰地寫(xiě):

<local:ImageView Graphic="{Binding MyGraphic}" />

3. 在 ItemList 中使用

ListBox 中批量展示多個(gè) GraphicInfo 時(shí),就非常自然:

<ListBox ItemsSource="{Binding Graphics}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:ImageView Graphic="{Binding}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

這里的 Binding 就是每個(gè) GraphicInfo,通過(guò)依賴(lài)屬性綁定到控件,不會(huì)和 DataContext 混用。

4. 對(duì)比與總結(jié)

使用 DataContext 的方式

? 簡(jiǎn)單,少寫(xiě)一個(gè)依賴(lài)屬性
? 容易和控件內(nèi)部 MVVM 沖突
? 在 ItemList 中語(yǔ)義不清晰

使用依賴(lài)屬性的方式

? 更加清晰,控件的 DataContext 可以獨(dú)立使用
? 在 ItemList 中使用更自然
? 可以在依賴(lài)屬性的回調(diào)里處理邏輯(如回寫(xiě) View

最佳實(shí)踐

  • 如果控件只是簡(jiǎn)單的 UI 展示,內(nèi)部不需要額外綁定,可以用 DataContext。
  • 如果控件要在 ItemList 中使用,或者內(nèi)部還需要用自己的 DataContext,推薦使用依賴(lài)屬性。

我個(gè)人在項(xiàng)目里最終采用了 依賴(lài)屬性模式,不僅解耦了數(shù)據(jù)和視圖,還能方便在列表場(chǎng)景下使用。

以上就是WPF自定義控件綁定數(shù)據(jù)對(duì)象的最佳實(shí)踐的詳細(xì)內(nèi)容,更多關(guān)于WPF自定義控件綁定數(shù)據(jù)對(duì)象的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VB.NET中Caching的使用方法

    VB.NET中Caching的使用方法

    Caching緩存,就是將一些生成代價(jià)比較大的常用數(shù)據(jù),保存起來(lái)重用。一般數(shù)據(jù)都保存在內(nèi)存中,因?yàn)閺膬?nèi)存中讀取數(shù)據(jù)比從數(shù)據(jù)庫(kù)等其他地方要快。
    2013-04-04
  • 基于WPF編寫(xiě)一個(gè)串口轉(zhuǎn)UDP工具

    基于WPF編寫(xiě)一個(gè)串口轉(zhuǎn)UDP工具

    串口是設(shè)備和上位機(jī)通信的常用接口,UDP則是網(wǎng)絡(luò)通信常用的通信協(xié)議,串口和UDP之間的相互轉(zhuǎn)換是非常有意義的。本文就利用WPF編寫(xiě)一個(gè)串口轉(zhuǎn)UDP工具,需要的可以參考一下
    2023-04-04
  • C#求點(diǎn)集的最小包圍矩形

    C#求點(diǎn)集的最小包圍矩形

    這篇文章主要為大家詳細(xì)介紹了C#求點(diǎn)集的最小包圍矩形,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C#實(shí)現(xiàn)帶進(jìn)度條的ListView

    C#實(shí)現(xiàn)帶進(jìn)度條的ListView

    這篇文章主要介紹了C#實(shí)現(xiàn)帶進(jìn)度條的ListView 的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • C#編程自學(xué)之類(lèi)和對(duì)象

    C#編程自學(xué)之類(lèi)和對(duì)象

    C#一種面向?qū)ο蟮木幊陶Z(yǔ)言,是專(zhuān)門(mén)為.NET應(yīng)用而開(kāi)發(fā)出的語(yǔ)言。在.NET運(yùn)行庫(kù)的支持下,.NET框架的各種優(yōu)點(diǎn)在C#中表現(xiàn)得淋漓盡致。所以學(xué)習(xí)類(lèi)和對(duì)象以及如何運(yùn)用它們是非常重要!
    2015-10-10
  • C# ListBox中的Item拖拽代碼分享

    C# ListBox中的Item拖拽代碼分享

    在本文中我們給大家分享了關(guān)于C#的ListBox中的Item拖拽的功能代碼分享,對(duì)此有需要的朋友參考學(xué)習(xí)下。
    2018-03-03
  • C#實(shí)現(xiàn)一個(gè)Word保護(hù)性模板文件

    C#實(shí)現(xiàn)一個(gè)Word保護(hù)性模板文件

    這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)一個(gè)Word保護(hù)性模板文件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下
    2024-01-01
  • C# Onnx CenterNet實(shí)現(xiàn)目標(biāo)檢測(cè)的示例詳解

    C# Onnx CenterNet實(shí)現(xiàn)目標(biāo)檢測(cè)的示例詳解

    這篇文章主要為大家詳細(xì)介紹了C# Onnx CenterNet實(shí)現(xiàn)目標(biāo)檢測(cè)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • C#多線程之取消架構(gòu)介紹

    C#多線程之取消架構(gòu)介紹

    這篇文章介紹了C#多線程之取消架構(gòu),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#實(shí)現(xiàn)Bitmap類(lèi)型與Byte[]類(lèi)型相互轉(zhuǎn)化的示例詳解

    C#實(shí)現(xiàn)Bitmap類(lèi)型與Byte[]類(lèi)型相互轉(zhuǎn)化的示例詳解

    在C#編程中,Bitmap類(lèi)型和Byte[]類(lèi)型之間的相互轉(zhuǎn)化是圖像處理和數(shù)據(jù)傳輸中常見(jiàn)的需求,Bitmap類(lèi)型表示一個(gè)位圖圖像,而B(niǎo)yte[]類(lèi)型則是一個(gè)字節(jié)數(shù)組,本文將詳細(xì)介紹如何在這兩種類(lèi)型之間進(jìn)行相互轉(zhuǎn)化,需要的朋友可以參考下
    2024-07-07

最新評(píng)論