Getting rid of heavy Multivalue Converters : My Encounter with Win Form style WPF apps 2
I recently came across the situation where I had to refactor the WPF code written in Win Forms Style; Code was having a lot of MultiValueConverters used for building the DataContext / ItemSources for Controls/ ListVies/ DataGrids etc. Following is the example of one of the converters I am talking about:
<ListView.ItemsSource>
<MultiBinding Converter="{StaticResource ItemsSourceInsertConverter}">
<Binding
ElementName="EditorControl"
Path="EditorControl.ContextListEnabled" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.ParentComponent.Model.ModelList" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.ParentComponent.Model.CategoryModelList" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.ParentComponent.Model.ItemSortOrder" />
<Binding
ElementName="EditorControl"
Path="IsItemSourceMatrixInsertConverterSuspended" />
<Binding
ElementName="EditorControl"
Path="EditorControlModel.IsUpdating" />
<Binding
ElementName="EditorControl"
Path="EditorControlModel.ContextListEnabledInitialized" />
<Binding
BindsDirectlyToSource="true"
ElementName="listView" />
<Binding
ElementName="EditorControl"
Path="EditorControlModel" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.Plugin.FeatureManager.EditorCategoryFeatureEnabled" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.Plugin.FeatureManager.EditorMatrixFeaturesEnabled" />
</MultiBinding>
</ListView.ItemsSource>
Here is the approach I followed for cleaning up these kind of converters:
Step 1: Cleanup the unwanted converter code, fields, properties, events etc.
Step 2: Create a property in your View Model / Code-behind of the type returned by the converter(e.g. ObservableCollection<T>).
Step 3: Copy the converter code in your View Model (grouping all that in a region will be helpful).
Step 4: Remove the converter specific code(like value checks/conversions etc.) and update code to get the values passed to the parameter(ideally all the values passed to converter should be available in the VM or through VM members).
Step 5: Change the Convert method to a method returning the required type (created in step 2) and call this method at appropriate place to set the value of this property.
Step 6: Remove all the references of converter from code, use the property created in step 2 instead of converter.
Step 7: Exclude the converter from project.
Step 8: Resolve the errors, verify all the related functionality and fix broken features one by one.
It was a real pain to fix the errors due to removal of these type of converters, as I had to make sure that value of new property gets updated correctly (not whenever any of the previously bound property is updated but only when it makes sense); but this exercise provided me an opportunity to cleanup the code and fix various other issues and most importantly understand almost every other feature implemented in this control
Bottom Line: Converters are basically for converting values (of types not usable in UI) in your ViewModel/CodeBehind into a type suitable for usage in UI and not for building DataContext for your controls encapsulating complex business logic.