是否可以使用简单的操作方法 - 就像使用Caliburn.Micro一样 - 而不是使用MvvmCross绑定的命令?
示例:
public void Action()
{
Tip = 11;
}
<Button
android:text="Button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/button1"
local:MvxBind="Click Action" />
开箱即用,我测试了它。
虽然我发现了很多关于添加新的目标绑定的示例,但我没有找到关于添加新源绑定的单一内容。
更新
这与Rio绑定开箱即用。要使用它,请将MvvmCross MethodBinding NuGet包添加到 Android 项目。
答案 0 :(得分:3)
到目前为止,MvvmCross的重点一直是允许多平台目标绑定,其中源仍然主要是“香草”INotifyPropertyChanged
。
ViewModel结构存在一些偏差 - 例如:
MvxCommandCollection
- http://slodge.blogspot.co.uk/2013/03/fixing-mvvm-commands-making-hot-tuna.html 最近,该领域也记录了几个新的功能请求:
由于这些原因,我希望将来可以在这个领域展示更多功能......
话虽如此,如果你想让它今天正常工作,那么MvvmCross Binding是可以覆盖的,所以你可以很容易地做到这一点:
1.实现使用反射调用MethodInfo的ICommand
(为了完整性,这应该也可以使用参数) - 某种InvokeMethodCommand
(此代码留给读者!)
2.实现一个包含
MyMethodSourceBinding
的{{1}}类 - 类似于:
InvokeMethodCommand
3.使用您自己的实现覆盖MvvmCross注册的public class MyMethodSourceBinding : MvxSourceBinding
{
private readonly MethodInfo _methodInfo;
protected MyMethodSourceBinding(object source, MethodInfo methodInfo)
: base(source)
{
_methodInfo = _methodInfo;
}
public override void SetValue(object value)
{
// do nothing - not allowed
}
public override Type SourceType
{
get { return typeof(ICommand); }
}
public override bool TryGetValue(out object value)
{
value = new InvokeMethodCommand(source, _methodInfo);
return true;
}
}
,该实现可以检测何时存在方法 - 遗憾的是,大多数情况下今天都是剪切和粘贴编码 - 它会像
IMvxSourceBindingFactory
4.在您自己的自定义绑定构建器中提供此源绑定工厂 - 例如:
public class MySourceBindingFactory
: IMvxSourceBindingFactory
{
private IMvxSourcePropertyPathParser _propertyPathParser;
private IMvxSourcePropertyPathParser SourcePropertyPathParser
{
get
{
if (_propertyPathParser == null)
{
_propertyPathParser = Mvx.Resolve<IMvxSourcePropertyPathParser>();
}
return _propertyPathParser;
}
}
public IMvxSourceBinding CreateBinding(object source, string combinedPropertyName)
{
var tokens = SourcePropertyPathParser.Parse(combinedPropertyName);
return CreateBinding(source, tokens);
}
public IMvxSourceBinding CreateBinding(object source, IList<MvxPropertyToken> tokens)
{
if (tokens == null || tokens.Count == 0)
{
throw new MvxException("empty token list passed to CreateBinding");
}
var currentToken = tokens[0];
if (tokens.Count == 1)
{
return CreateLeafBinding(source, currentToken);
}
else
{
var remainingTokens = tokens.Skip(1).ToList();
return CreateChainedBinding(source, currentToken, remainingTokens);
}
}
private static MvxChainedSourceBinding CreateChainedBinding(object source, MvxPropertyToken propertyToken,
List<MvxPropertyToken> remainingTokens)
{
if (propertyToken is MvxIndexerPropertyToken)
{
return new MvxIndexerChainedSourceBinding(source, (MvxIndexerPropertyToken) propertyToken,
remainingTokens);
}
else if (propertyToken is MvxPropertyNamePropertyToken)
{
return new MvxSimpleChainedSourceBinding(source, (MvxPropertyNamePropertyToken) propertyToken,
remainingTokens);
}
throw new MvxException("Unexpected property chaining - seen token type {0}",
propertyToken.GetType().FullName);
}
private static IMvxSourceBinding CreateLeafBinding(object source, MvxPropertyToken propertyToken)
{
if (propertyToken is MvxIndexerPropertyToken)
{
return new MvxIndexerLeafPropertyInfoSourceBinding(source, (MvxIndexerPropertyToken) propertyToken);
}
else if (propertyToken is MvxPropertyNamePropertyToken)
{
//**************************
// Special code is here
var propertyToken = (MvxPropertyNamePropertyToken) propertyToken;
if (source != null)
{
var method = source.GetType().GetMethod(propertyToken.PropertyName, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
if (method != null)
{
return new MyMethodSourceBinding(source, method);
}
}
return new MvxSimpleLeafPropertyInfoSourceBinding(source,
(MvxPropertyNamePropertyToken) propertyToken);
// Special code ends here
//**************************
}
else if (propertyToken is MvxEmptyPropertyToken)
{
return new MvxDirectToSourceBinding(source);
}
throw new MvxException("Unexpected property source - seen token type {0}", propertyToken.GetType().FullName);
}
}
5.在安装过程中提供此绑定构建器
public class MyAndroidBindingBuilder
: MvxAndroidBindingBuilder
{
protected override IMvxSourceBindingFactory CreateSourceBindingFactory()
{
return new MvxSourceBindingFactory();
}
}
注意:此方法仅适用于高级用户...正如本问题的第一部分所述,我确实希望此区域中的代码发生很大变化,因此您可能还会遇到一些维护分叉的问题在这方面。 (事实上,GitHub回购中的西藏绑定分支在这方面的代码已经发生了很大变化!)