繁体   English   中英

使用Caliburn Micro从视图模型中的属性名称获取控制

[英]Get control from property name in viewmodel using Caliburn Micro

我想获得对绑定到给定属性名称的TextBox的引用。 我想这样做而不会改变视图。 有没有使用Caliburn Micro执行此操作的正确方法? 如果没有,什么是“足够好”的方法?

public class MweViewModel : PropertyChangedBase
{
    public MweViewModel() : base()
    {
        PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
        {
            // Find control (i.e. TextBox) bound to property with name e.PropertyName
            TextBox textBox = ...
        };
    }
}

我不一定要确定这是最明智的方法(这不是我自己尝试做的事情),请参阅Documentation ,其中提到了一个ViewModelBinder类,该类负责固定各种属性,方法, ViewModels各自的ViewModels

ViewModelBinder上的BindProperties函数负责解析属性与最终绑定到的UI元素之间的绑定。 您可以根据现有代码定义自己的函数,该代码会跟踪所有已建立的绑定,因此您将有一个记录,可在程序的其他地方使用。

使用现有代码将为您提供以下信息:

ViewModelBinder.BindProperties = (namedElements, viewModelType) =>
    {
        var unmatchedElements = new List<FrameworkElement>();

        foreach (var element in namedElements)
        {
            var cleanName = element.Name.Trim('_');
            var parts = cleanName.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries);

            var property = viewModelType.GetPropertyCaseInsensitive(parts[0]);
            var interpretedViewModelType = viewModelType;

            for (int i = 1; i < parts.Length && property != null; i++)
            {
                interpretedViewModelType = property.PropertyType;
                property = interpretedViewModelType.GetPropertyCaseInsensitive(parts[i]);
            }

            if (property == null)
            {
                unmatchedElements.Add(element);
                // Log.Info("Binding Convention Not Applied: Element {0} did not match a property.", element.Name);
                continue;
            }

            var convention = ConventionManager.GetElementConvention(element.GetType());
            if (convention == null)
            {
                unmatchedElements.Add(element);
                // Log.Warn("Binding Convention Not Applied: No conventions configured for {0}.", element.GetType());
                continue;
            }

            var applied = convention.ApplyBinding(
                interpretedViewModelType,
                cleanName.Replace('_', '.'),
                property,
                element,
                convention
                );

            if (applied)
            {
                // Log.Info("Binding Convention Applied: Element {0}.", element.Name);
            }
            else
            {
                // Log.Info("Binding Convention Not Applied: Element {0} has existing binding.", element.Name);
                unmatchedElements.Add(element);
            }
        }

        return unmatchedElements;
    };

在添加绑定时(设置了applied时),您便拥有了所需的所有信息。 然后,您可以存储特定的绑定(例如与TextBox相关的绑定)。

您可能会使用静态字典之类的东西(根据您的要求,可能有更合适的东西):

        ViewModel Type    Bound Property      List of Bound elements
             |                   |                      |
             |                   |                      |
Dictionary<Type, Dictionary<PropertyInfo, List<FrameworkElement>>>

您将必须对null /健全性检查保持谨慎。

还有其他一些使用辅助方法来获取绑定的属性/控件的解决方案,尽管它们通常不得不遍历可视化树,这样,您实际上是在绑定实际创建时进行了此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM