這個 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>
最後一個比較有意思,上個圖
