Binding, Converter, ConverterParameter, and DoubleAnimation

Nathan Sokalski 4,116 Reputation points
2020-09-17T21:19:36.63+00:00

I have a Binding to which I want to pass the value from a DoubleAnimation. Because ConverterParameter is not a Property, how can I use the value from a DoubleAnimation as a ConverterParameter?

Universal Windows Platform (UWP)
{count} votes

4 answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-09-18T04:47:23.49+00:00

    Hi,
    the ConverterParameter property can not be bound because it is not a dependency property.

    Since Binding is not derived from DependencyObject none of its properties can be dependency properties. As a consequence, a Binding can never be the target object of another Binding.

    There is however an alternative solution. You could use a MultiBinding with a multi-value converter instead of a normal Binding (you need implement IMultiValueConverter in yours resource "Substring").

      <TextBox>
        <TextBox.Text>
          <MultiBinding Converter="{StaticResource Substring}">
            <Binding Path="Text" ElementName="txtMessage"/>
            <Binding Path="Tag" ElementName="txtMessageOut"/>
          </MultiBinding>
        </TextBox.Text>
      </TextBox>
    

  2. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-09-21T07:13:14.22+00:00

    Hi,
    excuse me, here is another approach for UWP.

    <Page  
        x:Class="App1.Page15"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:local="using:App15"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        mc:Ignorable="d"  
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
      <StackPanel>  
        <StackPanel.Resources>  
          <local:MySubstringConverter x:Key="Substring" ConverterParameter="{Binding Tag, ElementName=txtMessageOut}" />  
        </StackPanel.Resources>  
        <TextBox x:Name="txtMessage"/>  
        <TextBox x:Name="txtMessageOut" Tag="end"/>  
        <TextBlock Text="{Binding Text, ElementName=txtMessage, Converter={StaticResource Substring}}"/>  
      </StackPanel>  
    </Page>  
    

    And converter:

      public class MySubstringConverter : DependencyObject, IValueConverter  
      {  
        public static readonly DependencyProperty ConverterParameterProperty =  
          DependencyProperty.RegisterAttached("ConverterParameter", typeof(string),  
          typeof(MySubstringConverter), new PropertyMetadata(string.Empty));  
        public static string GetConverterParameter(DependencyObject obj) => obj.GetValue(ConverterParameterProperty) as string;  
        public static void SetConverterParameter(DependencyObject obj, string value) => obj.SetValue(ConverterParameterProperty, value);  
      
        public object ConverterParameter  
        {  
          get { return GetValue(ConverterParameterProperty); }  
          set { SetValue(ConverterParameterProperty, value); }  
        }  
      
        public object Convert(object value, Type targetType, object parameter, string language)  
        {  
          // Converter functionality  
          return (value ?? "").ToString() + " - " + (this.ConverterParameter ?? "").ToString();  
        }  
      
        public object ConvertBack(object value, Type targetType, object parameter, string language)  
        {  
          throw new NotImplementedException();  
        }  
      }  
    

    Result:
    25949-x.gif

    0 comments No comments

  3. Nathan Sokalski 4,116 Reputation points
    2020-09-23T01:02:29.993+00:00

    That doesn't seem to be working for me. Here is my code:

    Public Class SubstringConverter : Inherits DependencyObject : Implements IValueConverter
        Public Shared ReadOnly ConverterParameterProperty As DependencyProperty = DependencyProperty.Register("ConverterParameter", GetType(Integer), GetType(SubstringConverter), New PropertyMetadata(0))
    
        Public Property ConverterParameter As Object
            Get
                Return GetValue(ConverterParameterProperty)
            End Get
            Set(ByVal value As Object)
                SetValue(ConverterParameterProperty, value)
            End Set
        End Property
    
        Public Function Convert(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.Convert
            Return value.ToString().Substring(0, If(Me.ConverterParameter Is Nothing, value.ToString().Length, Math.Min(CInt(Me.ConverterParameter), value.ToString().Length)))
        End Function
        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.ConvertBack
            Return String.Empty
        End Function
    End Class
    
    <ctrl:SubstringConverter x:Key="Substring" ConverterParameter="{Binding Tag,ElementName=txtMessageOut}"/>
    
    <TextBlock x:Name="txtMessageOut" Tag="3" Text="{Binding Text,ElementName=txtMessage,Converter={StaticResource Substring}}"/>
    

    If I use a literal for ConverterParameter it works. I used a regular DependencyProperty because it didn't look like an Attached one (is there a reason for an attached property?). Am I doing something wrong?

    0 comments No comments

  4. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-09-23T18:57:11.61+00:00

    Hi,
    try this code. Your code doesn't work. Check this code:

    PropertyMetadata(String.Empty)

    Return value.ToString().Substring(0, If(Me.ConverterParameter Is Nothing, value.ToString().Length, Math.Min(CInt(Me.ConverterParameter), value.ToString().Length)))

      Public Class MySubstringConverter
        Inherits DependencyObject
        Implements IValueConverter
    
        Public Shared ReadOnly ConverterParameterProperty As DependencyProperty =
          DependencyProperty.RegisterAttached("ConverterParameter", GetType(String),
          GetType(MySubstringConverter), New PropertyMetadata(String.Empty))
        Public Shared Function GetConverterParameter(obj As DependencyObject) As String
          obj.GetValue(ConverterParameterProperty).ToString()
        End Function
        Public Shared Sub SetConverterParameter(obj As DependencyObject, value As String)
          obj.SetValue(ConverterParameterProperty, value)
        End Sub
    
        Public Property ConverterParameter As Object
          Get
            Return GetValue(ConverterParameterProperty)
          End Get
          Set(value As Object)
            SetValue(ConverterParameterProperty, value)
          End Set
        End Property
    
        Public Function Convert(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.Convert
          Return If(value Is Nothing, "", value.ToString()) & " - " & If(Me.ConverterParameter Is Nothing, "", Me.ConverterParameter.ToString())
          'Return value.ToString().Substring(0, If(Me.ConverterParameter Is Nothing, value.ToString().Length, Math.Min(CInt(Me.ConverterParameter), value.ToString().Length)))
        End Function
    
        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.ConvertBack
          Throw New NotImplementedException()
        End Function
      End Class
    

    Try this Convert function:

    Public Function Convert(value As Object, targetType As Type, parameter As Object, language As String) As Object Implements IValueConverter.Convert
      Dim v = value.ToString
      Dim l1 = v.Length
      Dim l2 As Integer = 0
      If Me.ConverterParameter IsNot Nothing AndAlso Integer.TryParse(Me.ConverterParameter.ToString, l2) Then
        l1 = Math.Min(l2, l1)
      End If
      Return v.Substring(0, l1)
    End Function
    
    0 comments No comments