将IsEnabled的约定添加到Caliburn.Micro

时间:2012-01-28 08:52:48

标签: wpf caliburn.micro isenabled

如何为Caliburn.Micro添加一个自定义约定,用于控件的IsEnabled属性,例如NameEnabled绑定到IsEnabled并行Name绑定到Text TextBox上的CanSave

在某种程度上,我想要实现的类似于Save属性可用于启用/禁用绑定到{{1}}方法的按钮的方式,但对于所有控件都是通用的。

2 个答案:

答案 0 :(得分:12)

Caliburn.Micro现在( 1.3.1 )并不真正支持同一FrameworkElement的这种“多重”约定,你已经描述过了。

修改

但是你可以挂钩ViewModelBinder.BindProperties方法,然后你可以实现自己的额外对话。

我更进了一步,实现了一个可行的原型,但它不健壮,也不是优雅,可能不正确这样做。但它可以作为一个起点:

static AppBootstrapper()
{
    ConventionManager.AddElementConvention<FrameworkElement>(
         UIElement.IsEnabledProperty, 
         "IsEnabled", 
         "IsEnabledChanged");
    var baseBindProperties = ViewModelBinder.BindProperties;
    ViewModelBinder.BindProperties =
        (frameWorkElements, viewModels) =>
        {
            foreach (var frameworkElement in frameWorkElements)
            {
                var propertyName = frameworkElement.Name + "Enabled";
                var property = viewModels
                     .GetPropertyCaseInsensitive(propertyName);
                if (property != null)
                {
                    var convention = ConventionManager
                        .GetElementConvention(typeof(FrameworkElement));
                    ConventionManager.SetBindingWithoutBindingOverwrite(
                        viewModels,
                        propertyName,
                        property,
                        frameworkElement,
                        convention,                                          
                        convention.GetBindableProperty(frameworkElement));
                }
            }
            return baseBindProperties(frameWorkElements, viewModels);
       };
}

答案 1 :(得分:-4)

您可以通过在ViewModel中设置布尔属性来启用/禁用控件,并且只需绑定到XAML中的IsEnabled:

TextBox  Name="SerialNumber" IsEnabled="{Binding IsReadOnly}"...

ViewModel:
   private bool isReadOnly;
    public bool IsReadOnly
    {
        get { return isReadOnly; }
        set
        {
            this.isReadOnly = value;
            NotifyOfPropertyChange( () => IsReadOnly);
        }
    }