Question

How do I add a custom convention to Caliburn.Micro for the IsEnabled property of controls - something like having NameEnabled bound to IsEnabled in parallel to Name bound to Text on a TextBox.

In a way, what I want to achieve is similar to the way that a CanSave property can be used to enable/disable a button bound to a Save method, but generic for all controls.

Was it helpful?

Solution

Caliburn.Micro right now (1.3.1) doesn't really support this "multiple" conventions for the same FrameworkElement, what you have described.

EDIT:

However you can hook into the ViewModelBinder.BindProperties method and there you can implement your own extra convetion.

I went one step further and implemented a prototype which works, but it's not robust, nor elegant and probably not the correct way to do this. But it can be a starting point:

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

OTHER TIPS

You can enable/disable a control by setting a boolean property in your ViewModel and you just bind to IsEnabled in XAML:

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

ViewModel:
   private bool isReadOnly;
    public bool IsReadOnly
    {
        get { return isReadOnly; }
        set
        {
            this.isReadOnly = value;
            NotifyOfPropertyChange( () => IsReadOnly);
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top