2

I'm attempting to create a CustomControl which will have various properties affected by an enum found in a ViewModel. The CustomControl created will be called within a View.

I would like the enum binding to change a couple of things within the Control, these include:

  • Changing an Images source (images changed to are static within a folder created inside the CustomControl Library),
  • Alter a TextBlocks Text property, again, the text options will be static between one of X amount of cases (X being the number of possible enum states(also doesn't change)).

Keep in mind, these two DP's will be linked e.g. if bound enum is case x, the image source will change and the displayed text. Basically, the two exposed DP's here will be bound to the same enum, but use it differently.


So, my question is, what would be the best way to carry what is described above?

I've already thought about two possible ways:

  1. Expose useful DP types and bind these properties to the same enum (e.g Property1="{Binding someEnum}" Property2="{Binding someEnum}") and also provide a ValueConvertor to convert these enums to useful types which the CustomControl can then use,
  2. Or, expose a single DP which accepts an enum and then changes the properties somewhere else within the CustomControl code, depending on the value of the bound enum?

I am fairly comfortable with carrying out option 1 with a value convertor in the Views code-behind file. However, I would like to avoid doing it this way as it would make the control less independant.

Regarding option two, I'm not entirely sure how to do it this way so articles or a small explanation would help if you feel this is the way to go - Possibly implementing INoitifyPropertyChanged on the DP so the control knows it's value has been changed when the Bound enum changes?

Also, I am not limited to doing it the two ways described, if you feel there is a better way, please suggest it!

I am using WPF (C#) in conjunction with MVVM architecture (MVVM Light Toolkit).

Quick Note: I would like to avoid altering the ViewModel - The exposed enum and all logic there should remain as it is unless absoloutely necessary!

Thanks in advance for your replies and I will attempt to update this question as much as possible with responses and updates regarding personal progress with the issue as well as possible extra information which has been requested!

1 Answers1

0

Both of your solutions should work just fine.

For the second solution, all that you need is to register the dependecy property with a PropertyChangedCallback:

public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(EnumType), typeof(MyClass), new PropertyMetadata(new PropertyChangedCallback(MyPropertyChangedHandler)));

static void MyPropertyChangedHandler(DependencyObject obj, DependencyPropertyChangedEventArgs args)

Check this thread for usage of FrameworkPropertyMetadata, UIPropertyMetadata and PropertyMetadata When should I use FrameworkPropertyMetadata or UIPropertyMetadata over plain PropertyMetadata?

The advantage of your first solution is that it's light, you only need 2 ValueConvertors, there is no need for a dependency property, so that another dev could understand there is a tight dependency between the enum and those properties just by looking at your xaml. The disadvantage is that if you plan to use your custom control with the same logic in more than one place, copy pasting those convertors is not very neat.

The second solution, is a mirror to the first, you have the advantage of a greater level of reusability, but your logic gets embedded deep in your control.

Community
  • 1
  • 1
Andrei Gavrila
  • 853
  • 9
  • 19
  • Thanks very much for the quick reply. Just one question, using the method you've suggested, will I have to create a duplicate enum list to the one which is in my ViewModel in the CustomControls code so that they both contain the same elements? – user1467655 Jun 20 '12 at 09:35
  • No, you will bind your new dependency property to your ViewModel. Binding is a way of creating a connection between a target and a source, so you won't have to duplicate anything. – Andrei Gavrila Jun 20 '12 at 12:08
  • The problem is, I don't know what type to assign the DependencyProperty when I create it since the enum type in the VM is not available in my CustomControl. `DependencyProperty.Register("MyProperty", typeof(EnumType), typeof(MyClass), new PropertyMetadata(new PropertyChangedCallback(MyPropertyChangedHandler)));` - What should replace 'EnumType' here? Sorry for my confusion! – user1467655 Jun 20 '12 at 15:31
  • It should be your enum type; why is it not available in your CustomControl ? If it can't be available to your custom control then you should probably stick to solution no. 1 convertors. – Andrei Gavrila Jun 20 '12 at 16:07
  • I'm unsure as to why I can't access the enum type I created, I'm fairly new to programming! Anyway, I added a reference to the ViewModelLibrary which contains the enum type I need and added the respective using to my CustomControl.cs file. Everything works fine and I gain access the the enum type I need. The problem begins at run-time and the aplication fails to start with the error: 'The type or namespace name 'NamespaceHeader' could not be found (are you missing a using directive or an assembly reference?)'. Anyway, I feel we're going quite off topipc now, so I might just have to leave this! – user1467655 Jun 20 '12 at 16:59
  • 'The type or namespace name '' could not be found could have a multitude of causes. My first guess would be target framework http://stackoverflow.com/questions/4764978/the-type-or-namespace-name-could-not-be-found . You could open a new thread for your problem – Andrei Gavrila Jun 22 '12 at 09:11
  • Ugh, that's so frustrating, it was a target framework issue (solution to the question you linked). Thanks you so much for your help with everything! – user1467655 Jun 22 '12 at 09:57