所以你想要的是有一个委托列表,然后是一个将委托转换为方法名称的转换器。
在您的 ViewModel 中,让 Actions 属性返回一个委托列表。使用预定义的 Func,这是一个不带参数并返回 int 的方法:
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”和 lambda,它只返回具有我们自定义属性的方法。
- 您必须修改转换器以采用 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;
}
}
}