【问题标题】:Control naming conventions in Caliburn.Micro framework在 Caliburn.Micro 框架中控制命名约定
【发布时间】:2014-07-04 22:51:33
【问题描述】:

Caliburn.Micro 允许为视图和视图模型配置命名约定,但我找不到如何配置控件和方法之间的匹配。我知道我可以只使用 Message.Attach 附加属性,但如果可能的话,我想依赖约定。

Caliburn.Micro 的约定说方法必须与控件命名相同。但这里存在一个问题:它们的名称通常不同。例如,SaveCancel 是方法的好名称,但按钮的名称不好。 SaveButtonCancelButton 是按钮的好名称,但方法名称不好。考虑到 XAML 的类型没有 C# 严格,匈牙利表示法也很有用,但像 btnSavebtnCancel 这样的名称对于方法是不可接受的。

我能找到的最接近的东西是ConventionManager.GetPropertyCaseInsensitive,但它只适用于属性,不适用于方法。

问题:如何配置 Caliburn.Micro 的约定,使其将Save 方法附加到SaveButton 控件?

【问题讨论】:

    标签: c# .net mvvm naming-conventions caliburn.micro


    【解决方案1】:

    这不是我以前尝试过的东西,但是如果你看一下Documentation,就会提到一个ViewModelBinder 类,它负责修复属性、方法等的各种绑定。到他们各自的ViewModels

    对您的案例特别感兴趣:

    ViewModelBinder.BindActions 是一个 Func,因此可以完全 如果需要更换。通过添加或更改 ElementConventions ConventionManager 还将影响操作的组合方式。 更多内容如下。

    所以本质上,应该可以通过定义自己的BindActions 函数来获得您所追求的行为。

    作为一个起点,您可以查看sourceViewModelBinder.BindActions 并了解该函数当前是如何定义的。

    如果您删除 WinRT 特定代码,您会得到如下所示的内容(您可能必须删除 Log 调用):

    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;
    };
    

    您可以看到Caliburn.Micro 尝试通过将ViewModel 上的可用方法名称与相应View 中存在的控件名称进行比较来将方法绑定到控件。

    一种方法可能是简单地添加第二次尝试来查找控件,搜索带有Button 附加的方法名称。这似乎有点违反直觉(从名称中去掉按钮更符合逻辑)。

    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;
        }
    }
    

    显然,这意味着如果您有一个名为SaveButton 的控件和一个名为Save 的控件,则只有最后遇到的一个控件会正确连接。解决方案取决于您是要保留原来的绑定行为,还是只保留这个新行为。

    无论哪种情况,整个文档链接都值得一读,因为它提到了其他有趣的东西,例如 ViewModelBinder.ApplyConventionsByDefault 标志。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-14
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-24
      • 2014-11-12
      • 1970-01-01
      相关资源
      最近更新 更多