C# 控制Caliburn.Micro框架中的命名约定
Micro允许为视图和视图模型配置命名约定,但我找不到如何配置控件和方法之间的匹配。我知道我可以只使用C# 控制Caliburn.Micro框架中的命名约定,c#,.net,mvvm,naming-conventions,caliburn.micro,C#,.net,Mvvm,Naming Conventions,Caliburn.micro,Micro允许为视图和视图模型配置命名约定,但我找不到如何配置控件和方法之间的匹配。我知道我可以只使用Message.Attachattached属性,但如果可能的话,我希望使用约定 Micro的惯例规定,方法的名称必须与控件的名称相同。但这里存在一个问题:它们的名称常常不同。例如,Save和Cancel是方法的好名称,但按钮的坏名称SaveButton和CancelButton是按钮的好名称,但方法的坏名称。考虑到XAML的类型没有C#严格,匈牙利符号也很有用,但是像btnSave和btnCa
Message.Attach
attached属性,但如果可能的话,我希望使用约定
Micro的惯例规定,方法的名称必须与控件的名称相同。但这里存在一个问题:它们的名称常常不同。例如,Save
和Cancel
是方法的好名称,但按钮的坏名称SaveButton
和CancelButton
是按钮的好名称,但方法的坏名称。考虑到XAML的类型没有C#严格,匈牙利符号也很有用,但是像btnSave
和btnCancel
这样的名称对于方法来说是不可接受的
我能找到的最接近的东西是ConventionManager.getPropertyCaseSensitive
,但它只适用于属性,不适用于方法
问题:如何配置Caliburn.Micro的约定,使其将
保存
方法附加到保存按钮
控件?这不是我以前尝试过的方法,但是如果您查看,这里提到了一个ViewModelBinder
类,该类负责将各种属性、方法等绑定到各自的ViewModels
对您的情况特别感兴趣的是:
ViewModelBinder.BindActions是一个函数,因此可以完全
如果需要,请更换。通过添加或更改ElementConventions
ConventionManager还将影响行动的组合方式。
下面将详细介绍
因此,从本质上讲,通过定义自己的BindActions
函数,应该可以获得您想要的行为
首先,您可以查看查看ViewModelBinder.BindActions
的,并查看函数当前是如何定义的
如果删除特定于WinRT的代码,剩下的代码如下所示(您可能必须删除日志调用):
您可以看到,Caliburn.Micro
通过将ViewModel
上的可用方法名称与相应的视图中的控件名称进行比较,尝试将方法绑定到控件
一种方法可以是简单地添加第二次尝试来查找控件,使用附加的按钮搜索方法名称。这似乎有点违反直觉(从名称中去掉按钮更有逻辑意义)
if(foundControl==null)
{
//再次检查名为FrameworkElements的“按钮”
foundControl=unmatchedElements.FindName(method.Name+“按钮”);
if(foundControl==null)
{
Log.Info(“未应用操作约定:{0}没有可操作的元素”,method.Name);
继续;
}
}
显然,这意味着如果您有一个名为SaveButton
的控件和一个名为Save
的控件,则只有最后遇到的一个控件才能正确连接。解决方案取决于您是希望保留原始绑定行为,还是仅保留此新行为
无论哪种情况,都值得阅读整个文档链接,因为它提到了其他有趣的东西,如默认情况下的ViewModelBinder.applyconventions
标志
ViewModelBinder.BindActions =
(namedElements, viewModelType) =>
{
var methods = viewModelType.GetMethods();
var unmatchedElements = namedElements.ToList();
foreach (var method in methods)
{
var foundControl = unmatchedElements.FindName(method.Name);
if (foundControl == null)
{
Log.Info("Action Convention Not Applied: No actionable element for {0}.", method.Name);
continue;
}
unmatchedElements.Remove(foundControl);
var message = method.Name;
var parameters = method.GetParameters();
if (parameters.Length > 0)
{
message += "(";
foreach (var parameter in parameters)
{
var paramName = parameter.Name;
var specialValue = "$" + paramName.ToLower();
if (MessageBinder.SpecialValues.ContainsKey(specialValue))
paramName = specialValue;
message += paramName + ",";
}
message = message.Remove(message.Length - 1, 1);
message += ")";
}
Log.Info("Action Convention Applied: Action {0} on element {1}.", method.Name, message);
Message.SetAttach(foundControl, message);
}
return unmatchedElements;
};
if (foundControl == null)
{
// Check again for "<Method>Button" named FrameworkElements
foundControl = unmatchedElements.FindName(method.Name + "Button");
if (foundControl == null)
{
Log.Info("Action Convention Not Applied: No actionable element for {0}.", method.Name);
continue;
}
}