Display(AutoGenerateField = false) on properties

Topics: Feature Requests
Oct 6, 2011 at 6:34 PM

I sometimes like to bind my ViewModel to a Dataform. Unfortunately, the dataform picks up all the public properties from the base class (Screen). I've worked around this by handle the DataForm_AutoGeneratingField event and setting Cancel = true for these properties. This is fine but it gets repetitive.

Could we add the [Display(AutoGenerateField = false)] attribute to these properties? In particular:

  • DisplayName
  • IsActive
  • IsInitialized
  • IsNotifying
  • Parent

Michael.

Oct 9, 2011 at 11:06 PM

I filed a work item to remember evaluating your proposal: http://caliburnmicro.codeplex.com/workitem/168 

Oct 10, 2011 at 8:12 AM

@maird: Honestly, I would work around the issue using a proper interface on the VM side and a convention.

Let's say you have an IHaveFilteredFields just like this:

public interface IHaveFilteredFields
{
    IEnumerable<string> GetFilteredFields();
}

During the model bind phase (through a convention) you could apply to the Dataform a filtering delegate like this:

var filterAwareViewModel = viewModel as IHaveFilteredFields;
var dataForm = view as Dataform;

if (filterAwareViewModel != null && dataForm != null)
{
      dataForm.AutoGeneratingField += (s, e) => { e.Cancel = filterAwareViewModel.Contains(e.PropertyName); };
}

 In my opinion, it does not make sense to 'pollute' the base framework view-model classes with functionalities specific to some controls.

Oct 10, 2011 at 11:57 AM

That was my initial thought, too. However, since the mentioned attribute is part of the framework, I would like to ponder if it could be added with no harms (other than codebase pollution, obviously).
I personally avoid putting data model properties directly in Screen VMs, and prefer using an associated POCO submodel (it may be a DTO) to hold those data.
But it is likely a matter of tastes.

Oct 10, 2011 at 12:09 PM

I can understand your concern, but  in my opinion, the attribute is too generic to allow for a proper automatic handling. Who says that it is enough to set just the auto-generating property by default? What about the other properties? I think that we cannot know how such attribute is handled under different contextes, and it is impossible to try to address every issue it could cause.

We could define every property as virtual, and let the users specify required attributes as needed, but it is an overkill in my opinion. I think that the codebase should be modified if there is really no other way to handle the issue, but I don't think this is the case, since there are at least two (better?) ways to handle it.

On a side note, using the light-weight POCO approach, how do you wire together the properties from the original object and the sub-model, in case both implement INPC? Do you have use some extension methods to bind them, or you simply wire equivalent properties by hand?

Oct 10, 2011 at 6:10 PM

You are right. Just ignoring base Screen field may not fit all possible scenarios.

What I meant to say is that most of the time I don't use Screen VM to hold data in properties bound to UI, so I never hit this issue (well, to be fair I don't use DataForm too much at all).
I often use separated models, typically the very same DTOs used to communicate with services over the wire.
Hence I don't need to transfer data back and forth: I just expose the data model as a single property in the Screen VM. 
Whenever a DTO cannot be effectively bound to the UI, I copy its properties into a dedicated input model, often using AutoMapper.