question

njsokalski avatar image
0 Votes"
njsokalski asked ·

Binding, Converter, ConverterParameter, and DoubleAnimation

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?

windows-uwp-xaml
· 3
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello, can you show some code, such as data type, expected effect, etc. This can help us understand your needs better.

0 Votes 0 · ·
njsokalski avatar image njsokalski RichardZhang-MSFT ·

QA won't let me post much, so here is my XAML:

<Grid RowSpacing="10">
<TextBox x:Name="txtMessage" Text="Test Message"/>
<TextBlock x:Name="txtMessageOut" Tag="6" Text="{Binding Text,ElementName=txtMessage,Converter={StaticResource Substring},ConverterParameter={Binding Tag,ElementName=txtMessageOut}}"/>
</Grid>

My goal is to use a DoubleAnimation to change the ConverterParameter of the TextBlock (txtMessageOut). The best idea I could come up with was to bind to the Tag property and then modify the Tag property with the animation. If I use a literal in the ConverterParameter, it works fine. Is there a way to use an animation to modify the ConverterParameter?

0 Votes 0 · ·

Hello, in UWP, binding usually applies to dependency properties. In fact, it is difficult to use bindings to pass values in DoubleAnimation. If you want to dynamically modify the parameters in DoubleAnimation, you can try to dynamically create DoubleAnimation in code-behind.

0 Votes 0 · ·
PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

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>
· 3 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I probably should have mentioned in my original posting that I am using UWP, not WPF. From what I have read, UWP does not support MultiBinding (is this correct?), therefore I don't believe your answer will work for my scenario. Any other ideas? Thanks.

0 Votes 0 · ·

What about combing the answers into one response?

0 Votes 0 · ·

Hi,
excuse me. I write in my other answer an another approch for UWP.

0 Votes 0 · ·
PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

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





x.gif (38.7 KiB)
· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

njsokalski avatar image
0 Votes"
njsokalski answered ·

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?


· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

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



· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.