Skip to main content

Microsoft Silverlight

Unanswered Question Using ValueConverters in Custom Control Template BindingsRSS Feed

(0)

michael_weed
michael_...

Member

Member

29 points

38 Posts

Using ValueConverters in Custom Control Template Bindings

Is it possible to use a ValueConverter class in a custom control? 

The reason that I ask is that I have been unsuccessful in my attempts to do so. I currently have a custom control defined in a custom control assembly where the template visuals are defined in generic.xaml and the control logic is defined in a backing control class.  When I attempt to use a ValueConverter in binding one of the properties of one of the controls in the template, I get a runtime error indicating that the XAML parser can't parse the resulting markup.  Note that I get no compile-time error and the binding syntax appears to be correct.

Regards,

Mike Weed

bryant
bryant

Star

Star

9937 points

1,629 Posts

Silverlight MVP

Re: Using ValueConverters in Custom Control Template Bindings

You might want to use a TypeConverter in this case, not a value converter. I posted the difference here. Value converters are usually used with data binding, not template binding.

-- bryant

Blog | Twitter
_________________
Dont forget to click "Mark as Answer" on the post that helped you.

michael_weed
michael_...

Member

Member

29 points

38 Posts

Re: Using ValueConverters in Custom Control Template Bindings

Hi Bryant,

In my scenario, I am databinding.  I'm attempting to define a binding between a data class property and a property on my control.  But a ValueConverter is required to perform a type conversion between the property values.  And using "normal" binding syntax with a converter in generic.xaml is throwing a runtime error.

Regards,

Mike Weed

bryant
bryant

Star

Star

9937 points

1,629 Posts

Silverlight MVP

Re: Using ValueConverters in Custom Control Template Bindings

I don't think you do data binding in generic.xaml. Only templates go in there and I don't believe the data binding will work.

Can you post some sample code of what you're trying to do?

-- bryant

Blog | Twitter
_________________
Dont forget to click "Mark as Answer" on the post that helped you.

michael_weed
michael_...

Member

Member

29 points

38 Posts

Re: Using ValueConverters in Custom Control Template Bindings

Hi Bryant,

Data binding actually works just fine and it's what you need to do when using Data Templates within your control template (as I am).  The issue seems to be that it doesn't like the use of a converter in the data binding definition.  Below is an excerpt of my code.  The formatter is "pggFormatter" and the property is "Gender" on the "PersonGlyph" control in the ListBox Item DataTemplate:

 

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
    xmlns:controls="clr-namespace:PPL.Silverlight.Controls.PeopleExplorer;assembly=PPL.Silverlight.Controls.PeopleExplorer"    
    mc:Ignorable="d" d:DesignWidth="311" d:DesignHeight="350.783">
    
    <controls:PersonGlyphGenderFormatter x:Key="pggFormatter" />

<!-- Built-In Style for PersonList -->
    <Style TargetType="controls:PersonList">
        <Setter Property="Template">
            <Setter.Value>

                <!-- ControlTemplate -->
                <ControlTemplate TargetType="controls:PersonList">

                    <!-- Template's Root Visual -->
                    <Grid Margin="8,40,8,20" x:Name="peopleListContainer">
                        <ListBox x:Name="lbPeopleList" Style="{StaticResource PersonListListBoxStyle}" Background="{x:Null}" BorderThickness="0,0,0,0" Height="Auto" VerticalAlignment="Stretch" Margin="5,50,5,5" >
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Top" Orientation="Horizontal" Margin="2,2,2,2">
                                        <controls:PersonGlyph 
								        EmploymentStatus="{Binding Path=EmployeeStatus}" 
								        Gender="{Binding Path=Gender Mode=OneWay Converter={StaticResource pggFormatter}}"
								        SalaryType="{Binding Path=EmployeeClass}"
								        Margin="2,0,0,0" x:Name="personGlyph" />
                                        <TextBlock Text="{Binding Path=Name}" TextWrapping="NoWrap" x:Name="tbName" Margin="5,0,0,0"  VerticalAlignment="Center"  IsHitTestVisible="False"  FontSize="11" MaxWidth="250" Width="250"  />
                                        <TextBlock Text="{Binding Path=WorkPhone}" MaxWidth="86" x:Name="tbPhone"  Width="86" IsHitTestVisible="False"   FontSize="11"   TextWrapping="NoWrap" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                        <TextBlock Text="{Binding Path=MailCode}" MaxWidth="70" x:Name="tbMailCode"  Width="70" IsHitTestVisible="False" FontSize="11"  TextWrapping="NoWrap" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                        <TextBlock Text="{Binding Path=RespCtrDescription}" MaxWidth="250" x:Name="tbDepartment"  Width="250" IsHitTestVisible="False" FontSize="11" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                    </StackPanel>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                        <TextBlock HorizontalAlignment="Left" Margin="15,15,0,0" VerticalAlignment="Top" Text="The following individuals match your search criteria.  Select one for more information." TextWrapping="Wrap" Foreground="#FFFFFFFF" FontSize="14" Width="655.152"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
 

Regards,

Mike Weed

bryant
bryant

Star

Star

9937 points

1,629 Posts

Silverlight MVP

Re: Using ValueConverters in Custom Control Template Bindings

Ok, now I see what you mean. Smile

I think the problem is that your value converter doesn't exist as a resource on the page. Try moving it into the Grid.Resources and see if that works:

 

    <Style TargetType="controls:PersonList">
        <Setter Property="Template">
            <Setter.Value>

                <!-- ControlTemplate -->
                <ControlTemplate TargetType="controls:PersonList">

                    <!-- Template's Root Visual -->
                    <Grid Margin="8,40,8,20" x:Name="peopleListContainer">
                       <Grid.Resources>  
                          <controls:PersonGlyphGenderFormatter x:Key="pggFormatter" />
                       </Grid.Resources>
                       <ListBox x:Name="lbPeopleList" Style="{StaticResource PersonListListBoxStyle}" Background="{x:Null}" BorderThickness="0,0,0,0" Height="Auto" VerticalAlignment="Stretch" Margin="5,50,5,5" >
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Top" Orientation="Horizontal" Margin="2,2,2,2">
                                        <controls:PersonGlyph 
								        EmploymentStatus="{Binding Path=EmployeeStatus}" 
								        Gender="{Binding Path=Gender Mode=OneWay Converter={StaticResource pggFormatter}}"
								        SalaryType="{Binding Path=EmployeeClass}"
								        Margin="2,0,0,0" x:Name="personGlyph" />
                                        <TextBlock Text="{Binding Path=Name}" TextWrapping="NoWrap" x:Name="tbName" Margin="5,0,0,0"  VerticalAlignment="Center"  IsHitTestVisible="False"  FontSize="11" MaxWidth="250" Width="250"  />
                                        <TextBlock Text="{Binding Path=WorkPhone}" MaxWidth="86" x:Name="tbPhone"  Width="86" IsHitTestVisible="False"   FontSize="11"   TextWrapping="NoWrap" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                        <TextBlock Text="{Binding Path=MailCode}" MaxWidth="70" x:Name="tbMailCode"  Width="70" IsHitTestVisible="False" FontSize="11"  TextWrapping="NoWrap" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                        <TextBlock Text="{Binding Path=RespCtrDescription}" MaxWidth="250" x:Name="tbDepartment"  Width="250" IsHitTestVisible="False" FontSize="11" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                    </StackPanel>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                        <TextBlock HorizontalAlignment="Left" Margin="15,15,0,0" VerticalAlignment="Top" Text="The following individuals match your search criteria.  Select one for more information." TextWrapping="Wrap" Foreground="#FFFFFFFF" FontSize="14" Width="655.152"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
 

-- bryant

Blog | Twitter
_________________
Dont forget to click "Mark as Answer" on the post that helped you.

michael_weed
michael_...

Member

Member

29 points

38 Posts

Re: Using ValueConverters in Custom Control Template Bindings

Hi Bryant,

I tried this already with no luck.  I also tried it at the <ListBox.Resources> level, too, with the same error (XamlParseException: AG_UNKNOWN_ERROR) resulting.  If I remove the converter, everything else binds just fine and the control renders.  The PersonGlyph control renders as the default value, though, because the Gender property binding fails because of the lack of a converter (but no error is thrown).

That's the issue here:  The Gender property on the PersonGlyph control is an Enumeration defined in the control.  The corresponding Gender property on the data class being bound is also an Enumeration defined  in the data class.  The conversion code  should be as follows:

 

public class PersonGlyphGenderFormatter : IValueConverter {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            PersonAvatar.PersonAvatarGender genderOut;
            Person.GenderType genderIn = (Person.GenderType)value;
            if (genderIn == Person.GenderType.Male) {
                genderOut = PersonAvatar.PersonAvatarGender.Male;
            } else {
                genderOut = PersonAvatar.PersonAvatarGender.Female;
            }
            return genderOut;           
        }

        // No need to implement converting back on a one-way binding 
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            throw new NotImplementedException();
        }
 }
 

Regards,

Mike Weed

bryant
bryant

Star

Star

9937 points

1,629 Posts

Silverlight MVP

Re: Using ValueConverters in Custom Control Template Bindings

Sorry for the run around on this. I have a couple more questions:

1) If you run in debug mode, does your converter ever get hit? If it does, is it returning the correct value?

2) It seems like you really should have a TypeConverter here and then decorate the attribute with it instead of using a value converter. But that is just my opinion and maybe I just misundertanding things again.

-- bryant

Blog | Twitter
_________________
Dont forget to click "Mark as Answer" on the post that helped you.

michael_weed
michael_...

Member

Member

29 points

38 Posts

Re: Using ValueConverters in Custom Control Template Bindings

No problem.  I really appreciate the help.

When I run in debug mode with a breakpoint set at the beginning of the converter, the breakpoint is never reached.  This lends support to my theory that the XAML parser does not consider the converter-related markup in the binding markup to be valid XAML.  So I'm thinking that this might be a bug -- where data binding is supported in a custom control template but converters are not.

How exactly would a type converter work in this instance?

Regards,

Mike Weed

robmaransky
robmaransky

Member

Member

24 points

34 Posts

Re: Using ValueConverters in Custom Control Template Bindings

Did you ever figure out how to use the ValueConverter in this scenario? I encountered the same issue. I worked around it by using a TemplateBinding together with a DependencyProperty and then binding outside of generic.xaml.

Rob

sl.ayer
sl.ayer

Participant

Participant

840 points

158 Posts

Re: Using ValueConverters in Custom Control Template Bindings

Just wanted to point out that ValueConverters in templates work in Silverlight 3.0

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities