Modifying a ConverterParameter in Codebehind

Nathan Sokalski 4,111 Reputation points
2020-04-14T20:22:22.573+00:00

I have XAML with a Binding that uses an IValueConverter. I want to change the ConverterParameter of this Binding in my codebehind. Here is my codebehind that I am trying to use:

Dim foregroundbinding As Binding = CType(brd.Child, TextBlock).GetBindingExpression(TextBlock.ForegroundProperty).ParentBinding
foregroundbinding.ConverterParameter = "Selected"
CType(brd.Child, TextBlock).SetBinding(TextBlock.ForegroundProperty, foregroundbinding)

However, when I do this, I receive the following:

Exception thrown: 'System.Runtime.InteropServices.COMException' in Sudoku_Experimental.exe
WinRT information: The object is immutable.

How can I set the ConverterParameter from codebehind? Thanks.

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Fay Wang - MSFT 5,221 Reputation points
    2020-04-15T02:46:47.383+00:00

    Hello,

    Welcome to Microsoft Q&A!

    Exception thrown: 'System.Runtime.InteropServices.COMException' in Sudoku_Experimental.exe WinRT information: The object is immutable.

    Based on the BindingExpression.ParentBinding method, the Remarks Part of the document, it mentions

    You can't set the property values of a Binding object after that binding has been attached to a target element and target property. If you attempt this you'll get a run-time exception. So when you tried to set its ConverterParameter, it throwed the above exception.

    If you want to update its ConverterParameter, you can only create a new Binding to attach to your element. Or you can add a property in your Converter to replace the role of ConverterParameter. For example:

    public class MyConverter : IValueConverter  
    {  
    
        public string MyParameter { get; set; }  
    
        public object Convert(object value, Type targetType, object parameter, string language)  
        {  
            if (MyParameter == "UnSelected") {  
                return "UnSelected";  
            }  
    
            return value;  
        }  
    
        public object ConvertBack(object value, Type targetType, object parameter, string language)  
        {  
            throw new NotImplementedException();  
        }  
    }  
     
    

    .xaml:

    <Page.Resources>  
    
        <local:MyConverter MyParameter="UnSelected" x:Key="Converter1"/>  
    
    </Page.Resources>  
    

    .cs:

    When you tried to change the property:

    MyConverter conv = this.Resources["Converter1"] as MyConverter;  
    conv.MyParameter = "Selected";  
    
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Nathan Sokalski 4,111 Reputation points
    2020-04-17T15:01:34.617+00:00

    It may not be efficient, and maybe I should be doing it differently, but I just decided to create a new Binding as follows:

    CType(brd.Child, TextBlock).SetBinding(TextBlock.ForegroundProperty, New Binding() With {.Path = New PropertyPath("Status"), .Converter = CType(Me.Resources("PuzzleSquareTextBlock"), IValueConverter), .ConverterParameter = "Selected"})

    This works with no problems that I have noticed, so for the moment this is what I will be doing (should I manually dispose of the old Binding, or will the GC take care of that?). Thank you for your help, it's good to know that Binding properties cannot be modified in code.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.