天天看點

WPF ObjectDataProvider

這個

ObjectDataProvider東西真的是個神奇的存在。

等同于反射。

隻不過是寫在xaml中。

例如說我要把colors中所有的顔色列舉出來。

普通方法:

//CB是combobox
            this.CB.ItemsSource = typeof(Colors).GetProperties();      

使用objectdataprovider則為

<Window.Resources>
        <ObjectDataProvider x:Key="ODP" ObjectInstance="{x:Type Colors}" MethodName="GetProperties"/>
    </Window.Resources>
    <Grid>
        <ComboBox Height="120" x:Name="CB" ItemsSource="{Binding Source={StaticResource ODP}}"/>
    </Grid>      

從編寫的代碼數量來說

C#要簡單一點。

不過對于習慣編寫xaml和必須在xaml中使用時objectdataprovider要更加友善。

objectdataprovider可以讓方法綁定到控件,準确的說是方法的結果。

假如說有一個類,有一個方法且有兩個參數此方法會傳回這兩個數的和。

public class A
    {

        public int ADD(int a, int b) => a + b;

    }      
<Window.Resources>
        <ObjectDataProvider x:Key="ODP"  ObjectType="{x:Type local:A}" MethodName="ADD">
            <ObjectDataProvider.MethodParameters>
                <sys:Int32>12</sys:Int32>
                <sys:Int32>12</sys:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <TextBlock Text="{Binding Source={StaticResource ODP}}"/>
    </Grid>      

或者是

<Window.Resources>
       <local:A x:Key="A"/>
        <ObjectDataProvider x:Key="GetAdd" ObjectInstance="{StaticResource A}"  MethodName="ADD"   >
            <ObjectDataProvider.MethodParameters>
                <sys:Int32>1</sys:Int32>
                <sys:Int32>1</sys:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>


    <Grid>
        <TextBlock Text="{Binding Source={StaticResource GetAdd}}"/>
    </Grid>      

ObjectInstance和ObjectType隻有其中一個可以指派。

ObjectType的類型是Type

ObjectInstance的類型是Object

換句話說objecttype可以使用x:type進行指派,也隻有這種方式。

objectinstance則是可以通過staticresource的方式進行綁定,綁定的也是執行個體化後的元素。

把類修改為

public class A
    {
        private int a;
        private int b;
        public A(int a,int b)
        {
            this.a = a;
            this.b = b;
        }
        public A()
        {

        }
        public int ADD(int a, int b) => a + b;

        public int ADD() => this.a + this.b;
    }      

有了構造函數和重載方法。

xaml中如果想要使用構造函數和重載方法則是需要這麼寫

<Window.Resources>
        <ObjectDataProvider x:Key="GetAdd"  ObjectType="{x:Type local:A}" MethodName="ADD"   >
            <ObjectDataProvider.ConstructorParameters>
                <sys:Int32>3</sys:Int32>
                <sys:Int32>1</sys:Int32>
            </ObjectDataProvider.ConstructorParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <TextBlock Text="{Binding Source={StaticResource GetAdd}}"/>
    </Grid>      

最後值得注意的是MethodParameters這個屬性是不支援直接綁定的。

但是卻可以這麼操作

public class A
    {
        private int a;
        private int b;
        public A(int a,int b)
        {
            this.a = a;
            this.b = b;
        }
        public A()
        {

        }
        public int ADD(int a, int b) => a + b;

        public int ADD() => this.a + this.b;

        public string ADD(string A, string B) => A + B;
    }      
<Window.Resources>
        <local:A x:Key="A"/>
        <ObjectDataProvider x:Key="GetAdd"  ObjectType="{x:Type local:A}"  MethodName="ADD"   >
            <ObjectDataProvider.MethodParameters>
                <sys:String>A</sys:String>
                <sys:String>B</sys:String>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBox Grid.Column="0" Text="{Binding Source={StaticResource GetAdd}, Path=MethodParameters[0],UpdateSourceTrigger=PropertyChanged,BindsDirectlyToSource=True}"/>
        <TextBox Grid.Column="1" Text="{Binding Source={StaticResource GetAdd}, Path=MethodParameters[1],UpdateSourceTrigger=PropertyChanged,BindsDirectlyToSource=True}"/>
        <TextBlock Grid.Column="2" Text="{Binding Source={StaticResource GetAdd}}"/>
    </Grid>      

最後一個比較有意思,上個圖

WPF ObjectDataProvider