したがって、デリゲートのリストと、デリゲートをメソッド名に変換するコンバーターが必要です。
ViewModel で、Actions プロパティがデリゲートのリストを返すようにします。引数を取らず、int を返すメソッドである定義済みの Func を使用します。
public IEnumerable<Func<int>> Actions
{
get
{
List<Func<int>> list = new List<Func<int>>();
list.Add( AddFunction );
list.Add( SubstractFunction );
return list;
}
}
次に、コンバーターを実装します。通常、コンバーターは「ビュー」の一部であるため、分離コード cs ファイルに配置します。この変換Func<int>
は文字列に変換し、リフレクションを使用してそれを行います。
[ValueConversion( typeof( Func<int> ), typeof( string ) )]
public class FnConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
{
Func<int> fn = value as Func<int>;
return fn.Method.Name;
}
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
{
return null;
}
}
最後に、XAML でコンバーターを使用する必要があります。ただし、そのためには、コンバーターが適用されるコンボ ボックスのアイテム テンプレートを指定する必要があります。
<!-- earlier in code define the converter as a resource -->
<Window.Resources>
<src:FnConverter x:Key="conv" />
</Window.Resources>
...
<!-- now the combo box -->
<ComboBox Margin="4" ItemsSource="{Binding Path=Actions}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource conv}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
そうは言っても、さらに洗練された解決策は、ビューモデルに MethodInfo のリストを保持することだと思います。カスタム属性を使用してこのリストを生成します。いくつかのコードの下。次の点に注意してください。
- PresentingAttribute はカスタム属性です。System.Reflection.Attribute から派生します。何もありません。必要に応じて、「ラベル」、「説明」などのパラメーターを追加できます。
- コンボボックスに入れたいメソッドを「Presenting」でデコレーション
- 現在、Actions はリフレクションを使用しています。カスタム属性を持つメソッドのみを返すフィルター述語の「Where」とラムダに注意してください。
- MethodInfo を受け取るようにコンバーターを変更する必要があります。
namespace SO
{
class PresentingAttribute : Attribute
{
}
class FnVM
{
public int numA { get; set; }
public int numB { get; set; }
public IEnumerable<MethodInfo> Actions
{
get
{
return typeof( FnVM ).GetMethods().Where( minfo =>
minfo.GetCustomAttribute( typeof( PresentingAttribute ) ) != null
);
}
}
[Presenting]
public int AddFunction( )
{
return numA + numB;
}
[Presenting]
public int MulFunction( )
{
return numA * numB;
}
}
}