Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a convention for IsEnabled to Caliburn.Micro

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.

like image 845
Bevan Avatar asked Jan 28 '12 08:01

Bevan


1 Answers

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);
       };
}
like image 166
nemesv Avatar answered Sep 19 '22 01:09

nemesv