我正在使用转换器 -
public class EnumSwitchConverter : ConverterBase {
private object
_On = null,
_Off = null;
/// <summary>
/// Get or Set object returned when parameter is present in value.
/// </summary>
public object On {
get { return this._On; }
set { this._On = value; }
}
/// <summary>
/// Get or Set object returned when parameter is not present in value.
/// </summary>
public object Off {
get { return this._Off; }
set { this._Off = value; }
}
public override object Convert(
object value, Type targetType, object parameter, CultureInfo culture ) {
return ( ( Enum )value ).HasFlag( ( Enum )parameter )
? this.On : this.Off;
}
}
(ConverterBase
只是一个实现MarkupExtension
,IValueConverter
和IMultiValueConverter
的抽象类,因为我厌倦了手动执行此操作。)
我想使用此转换器绑定到Enum属性。如上所述,当enum是指定值时,转换器返回设置为On
属性的任何内容,如果不是,则转换器返回设置为Off
属性的任何内容。我想将两个不同的命令传递给On
和Off
属性。在执行操作时,当绑定的枚举与目标值匹配时,该按钮将调用设置为On
属性的命令,如果不匹配,该按钮将调用设置为Off
属性的命令。
<Button Command="{Binding
PropertySource.SomeEnumProperty,
Source={x:Static Application.Current},
Converter={myConverters:EnumConverter
On={}, Off={}}
ConverterParameter={x:Static myEnum:enumValue}/>
我有两个属性可以公开我想要进入On和Off的命令。
public partial class App : Application {
/*Stuff*/
public ICommand onCommand{ get{ return this._onCommand; } }
public ICommand offCommand{ get{ return this._offCommand; } }
}
我不想做以下事情 -
On={Binding OnCommand, Source={x:Static Application.Current}
首先,OnCommand
永远不会改变。其次,On
不是依赖属性,所以无论如何我都无法做到。我只想传递OnCommand
作为对转换器的On
属性的引用。
我如何在转换器中引用命令属性?
答案 0 :(得分:2)
我可以想到两种方法来做到这一点,另一种方式(加上@ mm8指出的第三种方式):
使命令成为静态。
public partial class App : Application {
public static ICommand OnCommand { get{ return _onCommand; } }
public static ICommand OffCommand { get{ return _offCommand; } }
}
XAML
<Button
Command="{Binding
PropertySource.SomeEnumProperty,
Source={x:Static Application.Current},
Converter={myConverters:EnumConverter
On={x:Static local:App.OnCommand},
Off={x:Static local:App.OffCommand}}
ConverterParameter={x:Static myEnum:enumValue}}"
/>
将命令保留为实例属性并写入另一个MarkupExtension
。
public class GetInstanceProp : MarkupExtension
{
public GetInstanceProp(String propname, Object source)
{
_source = source;
_propName = propname;
}
private Object _source;
private String _propName;
public override object ProvideValue(IServiceProvider serviceProvider)
{
var propInfo = _source.GetType().GetProperty(_propName);
return propInfo.GetValue(_source);
}
}
XAML
<Button
Command="{Binding
PropertySource.SomeEnumProperty,
Source={x:Static Application.Current},
Converter={myConverters:EnumConverter
On={local:GetInstanceProp OnCommand, {x:Static local:App.Current}},
Off={local:GetInstanceProp OffCommand, {x:Static local:App.Current}}
ConverterParameter={x:Static myEnum:enumValue}}"
/>
您需要了解您在此处所做的事情:标记扩展仅在解析XAML时评估一次且仅评估一次。这是标记扩展名。 GetProp
将为您提供该属性然后的值。如果它是一个没有setter的命令属性,那就可以了,它在构造函数中初始化,或者第一次任何人调用getter。就是我们来到这里的情况。但很多时候,事实并非如此。
mm8建议的另一个选项是从DependencyObject
而不是从MarkupExtension派生您的valueconverter。这意味着您必须在资源中创建它的实例,但这不是世界末日。然后你可以给它可绑定的依赖属性。
如果你真的厌倦了StaticResource
值转换器,你可以编写一个MarkupExtension
来返回依赖项对象/值转换器类的实例。 MarkupExtension
可以镜像其属性并将值转发给它。但到目前为止,我看不到任何投资回报率。