Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically change ConverterParameter (or any) property of a MultiBinding (or any other) resource at runtime?

i'm new to wpf and xaml. i find solutions of most of the problems (in other languages) by searching here n there or googling around but this one made me crazy. i searched a lot on google and browsed many forums, but it seems that this time i met with a real challenge!

I have following code in Window.Resources:

<my:NameConverter x:Key="NameConverter"/>

<MultiBinding x:Key="CustomerFullNameBinding" 
              Converter="{StaticResource NameConverter}"
              ConverterParameter="LastNameFirst">
     <Binding Path="FirstName"  />
     <Binding Path="MiddleName" />
     <Binding Path="LastName" />
</MultiBinding>

The NameConverter class returns full name by combining individual parts of the name. The return value is based on value of ConverterParameter which can be one of the following: FirstNameFirst, LastNameFirst, OnlyFirstName, OnlyLastName, Initials (there are a few more; but for simplicity, let's not consider them)

This code works fine. I use following to get the result:

<TextBlock Text="{DynamicResource CustomerFullNameBinding}"/>

However, the problem is that if i use the resource CustomerFullNameBinding 20 times in my code (like shown abovw) all of them would show the name in ONE particular format. (i.e. Here in the declaration of CustomerFullNameBinding i have set ConverterParameter="LastNameFirst" so all 20 references will show name in that way only.)

Now my question is can i make it more "generalized" so that the i can set the value of ConverterParameter dynamically? i.e. i can have multiple textblocks that can display full name in different formats. I know it is possible if we create multiple resources like follows:

 <MultiBinding x:Key="CustomerFullNameBinding_FirstNameFirst" 
               Converter="..." ConverterParameter="FirstNameFirst">
      ......
 </MultiBinding>
 <MultiBinding x:Key="CustomerFullNameBinding_LastNameFirst" 
               Converter="..." ConverterParameter="LastNameFirst">
      ......
 </MultiBinding>
 <MultiBinding x:Key="CustomerFullNameBinding_OnlyFirstName" 
               Converter="..." ConverterParameter="OnlyFirstName">
      ......
 </MultiBinding>

 ... and so on ...

But i dont want that, 'coz it'll really make my code too bulky, and most importantly it'll void concept of reusability of resources!

Please suggest me any possible solution.
Thanks in advance.

Note: I got the original idea from here. The similar working example can be found msdn.microsoft.com/en-us/library/ms771336.aspx.

Tags: wpf xaml staticresource dynamicresource binding

like image 686
mg007 Avatar asked Oct 26 '22 02:10

mg007


1 Answers

To be able to change the display mode used on each instance, I think I would have done it something like this:

  • Create a UserControl with 3 TextBlocks for displaying the 3 parts of the name.
  • Add properties to the above for the parts of the name to be targets of binding.
  • Add a property for the mode in which to display (FirstNameFirst, LastNameFirst, etc.)

The above requires a binding for each of the pieces of the name, so one way to simplify that would be to make a single property on the UserControl of a type NameData declared as a struct with First, Middle, and Last properties. Then you could still use a single MultiBinding to that property. The difference would be that your NameConverter would take the 3 pieces and return a new NameData struct instead of a formatted string.

<NameTextBlock NameData="{DynamicResource CustomerFullNameBinding}" NameDisplayMode="LastNameFirst" />

<NameTextBlock NameData="{DynamicResource CustomerFullNameBinding}" NameDisplayMode="FirstNameFirst" />

<NameTextBlock NameData="{DynamicResource CustomerFullNameBinding}" NameDisplayMode="Initials" />

<!-- and so on... -->

The idea is to decouple the formatting from the data.

The part that tripped things up was declaring one MultiBinding as a resource. Usually, there would be a MultiBinding on each TextBlock you are binding to so that you can change the ConverterParameter for each case.

Edit: I know you wanted to be able to change ConverterParameter, but that's not really possible due to the 1 instance of MultiBinding and ConverterParameter being a plain property rather than a DependencyProperty, which would be required to be the target of a DynamicResource or Binding.

like image 160
Joel B Fant Avatar answered Nov 15 '22 08:11

Joel B Fant