Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控制Caliburn.Micro框架中的命名约定_C#_.net_Mvvm_Naming Conventions_Caliburn.micro - Fatal编程技术网

C# 控制Caliburn.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

Micro允许为视图和视图模型配置命名约定,但我找不到如何配置控件和方法之间的匹配。我知道我可以只使用
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;
    }
}