主頁 > .NET開發 > 【翻譯】WPF中的資料系結運算式

【翻譯】WPF中的資料系結運算式

2021-06-09 14:59:40 .NET開發

有很多文章討論系結的概念,并講解如何使用StaticResources和DynamicResources系結屬性,這些概念使用WPF提供的資料系結運算式,在本文中,讓我們研究WPF提供的不同型別的資料系結運算式,

介紹

資料系結是一種強大的技術,它允許資料在UI元素和業務模型之間流動,當業務模型中的資料發生變化時,它會自動將更改反映到UI元素上,

Models Description
OneWay Source → Destination
TwoWay Source ←→ Destination
OneWayToSource Source ← Destination
OneTime Source → Destination (only once)

這可以通過WPF提供的不同型別的資料系結運算式來實作,

資料系結運算式的型別如下所示,

  • DataContext系結
  • RelativeSource系結
  • ItemSource系結

1、DataContext系結

DataContext是一個依賴屬性,它是系結的默認源,Datacontext沿著邏輯樹繼承,因此,如果您設定一個DataContext來控制邏輯樹中的所有子元素,它也將參考同一個DataContext,除非并且直到顯式指定了另一個源,

讓我們舉個例子來更詳細地理解它,

1.1 創建一個類Book,如下所示,

public class Book 
{  
    public string Name 
    {  
        get;  
        set;  
    }  
    public string Author 
    {  
        get;  
        set;  
    }  
}  

1.2 添加一個XAML檔案DataContextBinding.XAML并放置四個TextBlock,如下所示,

<Grid VerticalAlignment="Center">  
    <Grid.RowDefinitions>  
        <RowDefinition Height="40" />  
        <RowDefinition Height="40" />  
    </Grid.RowDefinitions>  
    <Grid.ColumnDefinitions>  
        <ColumnDefinition Width="Auto" />  
        <ColumnDefinition Width="Auto" />  
    </Grid.ColumnDefinitions>  
    <TextBlock Text="Book Name:" FontWeight="Bold" />  
    <TextBlock Grid.Column="1" />  
    <TextBlock Text="Author:" FontWeight="Bold" Grid.Row="1" />  
    <TextBlock Grid.Row="1" Grid.Column="1" />  
</Grid>  

現在,讓我們看看如何使用這個DataContext屬性來顯示資料,

它有兩種用法,如下所示,

  • 1.使用{Binding}運算式

用于直接系結DataContext,

創建類Book的實體,初始化其屬性,并將類的Name屬性分配給Window的DataContext屬性,

public partial class DataContextBinding: Window 
{  
    public DataContextBinding() 
    {  
        InitializeComponent();  
        //Create the instance  
        Book book = new Book();  
        //initialize the properties  
        book.Name = "Computer Networking";  
        //Assign the Property as DataContext  
        this.DataContext = book.Name;  
    }  
}  

由于DataContext是沿著邏輯樹和資料book繼承的,因此Name被系結到Control Window,Window的所有子元素也將參考同一個物件(book.Name),

要顯示資料,請將DataContext與Textblock系結,如下所示,

<TextBlock Text="Book Name:" FontWeight="Bold"/>  
<TextBlock Text="{Binding}" Grid.Column="1" />   

輸出

  1. 使用{Binding Property}運算式

系結Datacontext的屬性,

創建類Book的實體,初始化其屬性并將類的實體(Book)分配給Window的DataContext屬性,

Book book = new Book();  
//initialize the properties  
book.Name = "Computer Networking";  
book.Author = "James F. Kurose";  
//Assign the instance as DataContext  
this.DataContext = book;  

現在,讓我們看看輸出,

由于系結運算式{Binding}用于系結Book型別的DataContext物件,因此呼叫ToString()方法,并將資料顯示為字串,為了以正確的格式顯示資料,我們必須將資料物件的屬性與TextBlock系結,如下所示:

<TextBlock Text="Book Name:" FontWeight="Bold"/>  
<TextBlock Text="{Binding Name}" Grid.Column="1" />  
<TextBlock Text="Author:" FontWeight="Bold" Grid.Row="1" />  
<TextBlock Text="{Binding Author}" Grid.Row="1" Grid.Column="1"/>

系結運算式{Binding Name}用于系結DataContext系結的Name屬性,

輸出

2、RelativeSource 系結

RelativeSource是一個屬性,它用相對關系設定系結源以系結目標,此擴展主要用于必須將元素的一個屬性系結到同一元素的另一個屬性時,

RelativeSource有四種型別,如下所示,

  1. Self
  2. FindAncestor
  3. TemplatedParent
  4. PreviousData

讓我們一個一個詳細地探討一下,

2.1 Self

Self用于系結源和系結目標相同的場景中,物件的一個屬性與同一物件的另一個屬性系結,

例如,讓我們取一個高度和寬度相同的橢圓,

在XAML檔案中添加下面給出的代碼,寬度屬性與高度屬性相對系結,

<Grid>  
    <Ellipse Fill="Black" Height="100" Width="{Binding RelativeSource={RelativeSource Self},Path=Height}">  
    </Ellipse>  
</Grid>   

輸出

如果改變橢圓的高度,寬度也會相對變化,

2.2 FindAncestor

顧名思義,當系結源是系結目標的祖先(父級)之一時使用此選項,使用FindAncestor擴展,可以找到任何級別的祖先,

讓我們舉個例子來更清楚地理解它,

步驟

創建XAML,它表示下面給出的元素的邏輯樹,

<Grid Name="Parent_3">  
    <StackPanel Name="Parent_2">  
        <Border Name="Parent_1">  
            <StackPanel x:Name="Parent_0" Orientation="Vertical">  
                <Button></Button>  
            </StackPanel>  
        </Border>  
    </StackPanel>  
</Grid>  

現在,讓我們使用FindAncestor擴展將祖先的Name屬性系結到子元素button的Content屬性,

<Grid Name="Parent_3">  
    <StackPanel Name="Parent_2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100">  
        <Border Name="Parent_1">  
            <StackPanel x:Name="Parent_0" Orientation="Vertical">  
                <Button Height="50" Content="{Binding RelativeSource={RelativeSource FindAncestor,  
AncestorType={x:Type StackPanel},  
AncestorLevel=2},Path=Name}"></Button>  
            </StackPanel>  
        </Border>  
    </StackPanel>  
</Grid>  

輸出

AncestorType為“StackPanel”與AcestorLevel為“2”組合,將button的content屬性與StackPanel的Name屬性(Parent_2)系結在一起,

2.3 TemplatedParent

TemplatedParent是一個屬性,它使您能夠創建一個包含少量未知值的控制元件模板,這些值取決于應用ControlTemplate的控制元件的屬性,

讓我們舉個例子來更詳細地理解它

步驟

  1. 為按鈕創建一個ControlTemplate,如下所示,
<Window.Resources>  
    <ControlTemplate x:Key="template">  
        <Canvas>  
            <Ellipse Height="110" Width="155"  
             Fill="Black"/>  
            <Ellipse Height="100" Width="150"  
             Fill="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}">  
            </Ellipse>  
            <ContentPresenter Margin="35"  
             Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"/>  
       </Canvas>  
    </ControlTemplate>  
</Window.Resources>  

在上面給出的代碼中,橢圓的Fill屬性和ContentPresenter的Content屬性依賴于將應用此模板的控制元件的屬性值,

  1. 添加一個按鈕并對其應用模板,
<Button Margin="50" Background="Beige" Template="{StaticResource template}" Height="0" Content="Click me" FontSize="22">  
</Button>   

在應用模板時,按鈕的Background(Beige)與橢圓的Fill屬性相對系結,Content(Click me)與ContentPresenter的Content屬性相對系結,依賴值生效并給出以下輸出,

輸出

2.4 PreviousData

這是相對使用最少的方式,當資料被分析時,這就出現了,我們需要表示值相對于以前資料的變化,

讓我們舉個例子來更詳細地理解它,

步驟

  1. 創建一個類Data并實作INotifyPropertyChanged介面,如下所示
public class Data: INotifyPropertyChanged 
{  
    public int DataValue 
    {  
        get;  
        set;  
    }  
    public event PropertyChangedEventHandler PropertyChanged;  
    protected void OnPropertyChanged(string PropertyName) 
    {  
        if (null != PropertyChanged) 
        {  
            PropertyChanged(this,  
                new PropertyChangedEventArgs(PropertyName));  
        }  
    }  
}   
  1. 創建一個Data型別的串列并將其指定為DataContext,
public RelativeSourcePreviousData() 
{  
    InitializeComponent();  
    List < Data > data = https://www.cnblogs.com/Dotnet9-com/p/new List < Data > ();  
    data.Add(new Data() 
    {  
        DataValue = 60  
    });  
    data.Add(new Data() 
    {  
        DataValue = 100  
    });  
    data.Add(new Data() 
    {  
        DataValue = 120  
    });  
    this.DataContext = data;  
}   
  1. 在XAML檔案中添加ItemsControl,
<ItemsControl ItemsSource="{Binding}"></ItemsControl>  
  1. 為其創建ItemsPanel模板,如下,
<ItemsControl ItemsSource="{Binding}">  
    <ItemsControl.ItemsPanel>  
        <ItemsPanelTemplate>  
            <StackPanel Orientation="Vertical" />  
        </ItemsPanelTemplate>  
    </ItemsControl.ItemsPanel>  
</ItemsControl>  
  1. 現在,為了正確地表示資料,創建DataTemplate,如下所示,
<ItemsControl.ItemTemplate>  
    <DataTemplate>  
        <StackPanel Orientation="Horizontal">  
            <Grid Margin="30,20,0,0">  
                <Rectangle Width="80" Height="{Binding DataValue}" Fill="Blue" />  
                <TextBlock Foreground="White" Margin="35,0,0,0" Text="{Binding DataValue}"></TextBlock>  
            </Grid>  
            <TextBlock Margin="30,20,0,0" Text="Previous Data:"></TextBlock>  
            <TextBlock VerticalAlignment="Center" Margin="5,20,0,0" Text="{Binding  
             RelativeSource={RelativeSource PreviousData}, Path=DataValue}" />  
        </StackPanel>  
    </DataTemplate>  
</ItemsControl.ItemTemplate>  

輸出

藍色框的高度是串列中專案的值,舊資料顯示在右側,該項的第一個值為“60”,因此,第一項沒有舊值,

3、ItemSource系結

在處理集合時使用,使用這個系結運算式,您可以非常容易地讀取SelectedItem的屬性,斜杠是一種特殊運算子,用于處理集合中的當前項,

下面給出了三種運算式,

  1. {Binding / }
  2. {Binding Collection / }
  3. {Binding Collection / Property}

3.1 {Binding / }

此運算式用于系結DataContext中的當前項,

讓我們采取一個示例:

在下面給出的示例中,DataContext是字串型別的國家/地區的集合,并且與Listbox系結在一起,

步驟

  1. 創建一個Countries類并添加一個GetCountriesName()方法,該方法回傳string資料型別的國家的集合,如下所示,
public class Countries 
{  
    public static List <string> GetCountriesName() 
    {  
        List <string> countries = new List <string> ();  
        foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) 
        {  
            RegionInfo country = new RegionInfo(culture.LCID);  
            if (!countries.Contains(country.EnglishName))  
                countries.Add(country.EnglishName);  
        }  
        countries.Sort();  
        return countries;  
    }  
}  
  1. 添加一個XAMl檔案,一個ListBox和TextBlock,如下所示,
<DockPanel Name="Collection">  
    <ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">  
    </ListBox>  
    <TextBlock DockPanel.Dock="Top" />  
</DockPanel>  
  1. 創建類Countries的實體并將Countries集合指定為DataContext,
public CurrentItemCollection() 
{  
    InitializeComponent();  
    Countries countries = new Countries();  
    this.DataContext = countries.GetCountriesName()  
} 
  1. 系結TextBlock的Text屬性以將其系結到集合的當前選定項,如下所示,
<TextBlock DockPanel.Dock="Top" Text="{Binding /}" />  

輸出

一旦串列項被選中,它將在右側顯示所選國家/地區,

3.2 {Binding Collection /}

此運算式用于系結DataContext中集合屬性的當前項,

例如,

DataContext是Countries類

Collection屬性是CounriesList,它與ListBox系結,

步驟

  1. 使用上面創建的類似的國家類,只是略有不同,創建回傳型別為RegionInfo的方法,
public static List <RegionInfo> GetCountries() 
{  
    List <RegionInfo> countries = new List <RegionInfo> ();  
    foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) 
    {  
        RegionInfo country = new RegionInfo(culture.LCID);  
        if (countries.Where(p => p.Name == country.Name).Count() == 0)  
            countries.Add(country);  
    }  
    return countries.OrderBy(p => p.EnglishName).ToList();  
}
  1. 添加RegionInfo型別的CountriesList屬性,
private List <RegionInfo> countries = null;  
public List <RegionInfo> CountriesList 
{  
    get 
    {  
        if (countries == null)  
            countries = GetCountries();  
        return countries;  
    }  
}  

下面是CountriesList集合中的值的截圖,

  1. 將類Countries指定為DataContext,并將Listbox與DataContext的CountriesList屬性系結,
<Window.Resources>  
    <vm:Countries x:Key="Countries"></vm:Countries>  
</Window.Resources>  
<Grid>  
    <DockPanel Name="Collection" DataContext="{StaticResource Countries}">  
        <ListBox ItemsSource="{Binding CountriesList}" IsSynchronizedWithCurrentItem="True">  
            <ListBox.ItemTemplate>  
                <DataTemplate>  
                    <TextBlock Text="{Binding EnglishName}"></TextBlock>  
                </DataTemplate>  
            </ListBox.ItemTemplate>  
        </ListBox>  
    </DockPanel>  
</Grid>  
  1. 要計算CountriesList屬性的當前項,請系結TextBlock的Text屬性,如下所示,
<TextBlock DockPanel.Dock="Top" Text="{Binding CountriesList/}" HorizontalAlignment="Center" FontSize="16" VerticalAlignment="Center" />

輸出

右側顯示DataContext(CountriesList)中集合的當前項(CountriesList),

3.3 {Binding Collection / Property}

此運算式用于系結DataContext中集合的當前項的屬性,

例如,如果必須計算CountriesList集合的當前項的特定屬性,

在這個例子中,我想顯示屬性“EnglishName”的值,

為此,系結TextBlock的Text屬性,如下所示,

<TextBlock DockPanel.Dock="Top" Text="{Binding CountriesList/EnglishName}" />  

輸出

現在,當串列中的項被選中時,它顯示屬性“EnglishName”的值,

結論

我已經詳細介紹了所有的資料系結運算式,我希望這有助于您理解系結的概念和WPF提供的運算式,


時間如流水,只能流去不流回,

  • 作者:Swati Gupta
  • 原文標題:DataBinding Expressions In WPF
  • 原文鏈接:https://www.c-sharpcorner.com/article/data-binding-expression-in-wpf/
  • 翻譯、編輯:沙漠盡頭的狼
  • 公眾號:Dotnet9
  • 日期:2021-05-04

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/285409.html

標籤:WPF

上一篇:使用DevExpress的GridControl實作多層級或無窮級的嵌套串列展示

下一篇:WPF教程十三:自定義控制元件進階可視化狀態與自定義Panel

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more