1. 程式人生 > >【.net 深呼吸】實時獲取計算結果

【.net 深呼吸】實時獲取計算結果

urn 找到 method 值傳遞 派生類 change windows 初學 推出

上次老周介紹了在 UWP 應用中通過 x:Bind 標記來綁定到方法,以實現實時獲取計算結果。今天,咱們來耍耍WPF上面的實現方法。

雖然,WPF 沒有 x:Bind 標記(暫時沒有,以後不好說),但 WPF 在數據綁定方面也是有很強大的引擎D,畢竟它是 .net 框架一部分。其實,當年在 .net 1.x 的時候,老周就推測微軟會推出新的框架的,只是當時還不知道它叫 WPF,為啥呢。因為當時老周發現,Windows 窗體應用相關的類型都放在 System.Windows.Forms 命名空間下,不知道你初學.net 時會不會感到很奇怪,反正老周覺得很怪,為什麽不直接放到 System.Windows 命名空間下呢,所以,我就想到,System.Windows 命名空間下將來肯定要放別的東西。

後來,.net 2.0 SP1,.net 3.0,尤其是 .net 3.5 的時候,這個框架逐步定型,故我一直認為 4.0 是.net 成熟的標誌。

好了,不上歷史課了,咱們還是繼續上編程課吧。

在 WPF 中,提供了一種很好玩的綁定模型——DataSourceProvider,當然,它是抽象類,不能直接用的,直接用的話會抽風。它的派生類為我們實現了兩種形式的“間接綁定”:XmlDataProvider 可以組件或鏈接外部的XML文檔;ObjectDataProvider可以綁定到某個類型或該類型的實例對象,而且還可以綁定到類型的方法成員上,實例方法或是靜態方法皆可。

要實時獲取計算結果,應當使用 ObjectDataProvider 類,如果要綁定實例方法,除了要為 ObjectType 屬性設定目標類型的Type外,還要將該類型的實例賦給 ObjectInstance 屬性;如果是綁定到靜態方法,那就不必要指定 ObjectInstance 屬性了。

然後,通過 MethodName 屬性設置要綁定的方法的名字,如果方法有參數,向 MethodParameters 列表添加元素,有幾個參數就傳幾個值,元素的順序與方法參數的聲明一致即可。註意這個方法要有返回值,因為綁定目標要從該方法獲取計算結果的。

下面咱們用一個示例來說明一下。

首先,得聲明一個類,用來進行計算,我就用一個靜態方法吧,簡單方便。

    public class Demo
    {
        public static double GetMin(double a, double b)
        {
            return Math.Min(a, b);
        }
    }

這個方法很簡單,幼兒園層次的,輸入兩個數值,返回其中較小的值。

然後,重點來了,在 XAML 文檔中聲明 ObjectDataProvider 實例。

        <Grid.Resources>
            <local:StrAndDoubleConverter x:Key="cvt"/>
            <ObjectDataProvider x:Key="dprd" ObjectType="{x:Type local:Demo}"
                                MethodName="GetMin">
                <ObjectDataProvider.MethodParameters>
                    <sys:Double>0</sys:Double>
                    <sys:Double>0</sys:Double>
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
        </Grid.Resources>

StrAndDoubleConverter 是一個自定義的轉換器,在 string 和 double 之間轉化,這個大家可以無視。

ObjectType 屬性指定的是我們剛剛定義的 Demo 類,MethodName 方法指定剛剛那個靜態方法。由於這個方法需要兩個輸入參數,所以,得向 MethodParameters 中添加兩個 double 值,默認全設為 0。

下面我們在 UI 上放兩個 TextBox 控件,用來輸入兩數值,並且當輸入的值改變時,自動把值傳遞到 ObjectDataProvider 對象的 MethodParameters 列表中。如何實現呢?數據綁定,把 TextBox 的 Text 屬性與 MethodParameters 中的元素進行綁定,並且是雙向綁定。

            <TextBox Grid.Row="0" Grid.Column="1" Margin="4" Text="{Binding Source={StaticResource dprd},BindsDirectlyToSource=True,Mode=TwoWay,Path=MethodParameters[0],Converter={StaticResource cvt},UpdateSourceTrigger=PropertyChanged}"/>
            <TextBox Grid.Row="1" Grid.Column="1" Margin="4" Text="{Binding Source={StaticResource dprd},BindsDirectlyToSource=True,Mode=TwoWay,Path=MethodParameters[1],Converter={StaticResource cvt},UpdateSourceTrigger=PropertyChanged}"/>

此處, BindsDirectlyToSource 屬性記得要設置為 true,這個是啥意思呢?它的意思就是,這個Binding是直接綁定到 Source 屬性所指定的對象,還是原始數據源。在本例這個綁定模型中,原始數據源應為 Demo 類,而中間數據源是 ObjectDataProvider 對象,因此,如果不把 BindsDirectlyToSource 屬性設置為true,那麽這個 Binding 所相對的是 Demo 類,如果 BindsDirectlyToSource 屬性為 true,那麽該Binding的相對源就會指向 ObjectDataProvider 對象,這樣一來,Path 屬性才能找到 MethodParameters 列表中的元素。

其中,[0] 表示列表中的第一個元素,即傳給綁定方法的第一個參數,同理,[1] 就是指向第二個參數。為了能夠在 Text 屬性更改時更新方法參數,需要設置 UpdateSourceTrigger=PropertyChanged,Mode=TwoWay。

接著,我們聲明一個 TextBlock 元素,同樣也是綁定到前面在資源中聲明的 ObjectDataProvider 對象上,實時獲取計算的結果。

        <TextBlock Grid.Row="1" Margin="5">
            <Run Text="較小的那個數:"/>
            <Run Text="{Binding Source={StaticResource dprd},Mode=OneWay}" Foreground="DarkGreen" FontSize="18"/>
        </TextBlock>

這裏只需要讀取結果即可,所以,Mode 為 OneWay 即可。如果計算需要花較長時間,可以設置 IsAsynchronous 屬性為 true,這樣可以優化 UI 的響應速度。

好了,示例完成了,咱們來看看運行效果吧。

技術分享

而後,老周嘗試把方法的返回值改為 void,以 out 和 ref 方式進行計算結果賦值,但綁定後不能獲得正確的結果。

示例源代碼下載請點擊這裏。

【.net 深呼吸】實時獲取計算結果