Silverlight 2 binds data to transforms?
I am working on creating a tag cloud in Silverlight 2 and am trying to bind data from a List collection to a scale conversion to TextBlock. I get an error on startup AG_E_PARSER_BAD_PROPERTY_VALUE
. Is it possible to convert data binding values ββin Silverlight 2? If I couldn't do something with the FontSize = {Binding Weight * 18} effect to multiply the tag weight by the base font size? I know this won't work, but what is the best way to calculate property values ββfor items in the DataTemplate?
<DataTemplate>
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextWrapping="Wrap" d:IsStaticText="False" Text="{Binding Path=Text}" Foreground="#FF1151A8" FontSize="18" UseLayoutRounding="False" Margin="4,4,4,4" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding Path=WeightPlusOne}" ScaleY="{Binding Path=WeightPlusOne}"/>
</TransformGroup>
</TextBlock.RenderTransform>
source to share
The problem lies in Rule # 1 from this post :
The target of data binding must be a FrameworkElement.
Since ScaleTransform is not a FrameworkElement, it does not support binding. I tried linking SolidColorBrush to test this and got the same error as in ScaleTransform.
So, to get around this, you can create a control that exposes the dependency property of your tag data type. Then add a modified event property that binds the data properties of your tag to the properties in the control (one of which will be the scale transform). Here is the code I used to test this.
element control:
<ItemsControl x:Name="items">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:TagControl TagData="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
xaml control tag:
<UserControl x:Class="SilverlightTesting.TagControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<TextBlock x:Name="text" TextWrapping="Wrap" FontSize="18" Margin="4,4,4,4">
<TextBlock.RenderTransform>
<ScaleTransform x:Name="scaleTx" />
</TextBlock.RenderTransform>
</TextBlock>
</UserControl>
tag control code
public partial class TagControl : UserControl
{
public TagControl()
{
InitializeComponent();
}
public Tag TagData
{
get { return (Tag)GetValue(TagDataProperty); }
set { SetValue(TagDataProperty, value); }
}
// Using a DependencyProperty as the backing store for TagData. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TagDataProperty =
DependencyProperty.Register("TagData", typeof(Tag), typeof(TagControl), new PropertyMetadata(new PropertyChangedCallback(TagControl.OnTagDataPropertyChanged)));
public static void OnTagDataPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var tc = obj as TagControl;
if (tc != null) tc.UpdateTagData();
}
public void UpdateTagData()
{
text.Text = TagData.Title;
scaleTx.ScaleX = scaleTx.ScaleY = TagData.Weight;
this.InvalidateMeasure();
}
}
It looks like the overkill is just setting one property, but I couldn't find an easier way.
source to share