Search code examples
wpfxaml.net-coredependency-propertiestypeconverter

WPF GridLength dependency property: cannot convert from System.String


I'm developing a WPF application with this UserControl:

public partial class MyUserControl : UserControl
{
    public GridLength IconColumnWidth
    {
        get { return (GridLength)GetValue(IconColumnWidthProperty); }
        set { SetValue(IconColumnWidthProperty, value); }
    }

    public static readonly DependencyProperty IconColumnWidthProperty =
        DependencyProperty.Register(nameof(IconColumnWidth), typeof(GridLength), typeof(MyUserControl), new PropertyMetadata(new GridLength(0), new PropertyChangedCallback(SetIconColumnWidth)));

    public static void SetIconColumnWidth(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyUserControl target = (MyUserControl)d;
        target.MainGrid.ColumnDefinitions[0].Width = ((GridLength)e.NewValue);
    }
}

And I'm trying to use it as follow:

<MyUserControl x:Name="Total" Value="{Binding TotalCycles, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" IconColumnWidth="50"  />

However, I'm getting error 'TypeConverter cannot convert from System.String'.

I tried to apply this attribute on my DependencyProperty field

[TypeConverter(typeof(GridLengthConverter))]

but nothing changed. What am I doing wrong?


Solution

  • I finally found a way to solve my issue. Not sure if this is the proper way but since it's working without problems and it's pretty straighforward, I post my solution as accepted answer. I'll be happy to update this post (and eventually change accepted answer) if someone will provide a better solution explaining its advantages.

    I tried multiple things, like setting attribute [TypeConverter(typeof(GridLengthConverter))] on property only, on dependency property field only or on both of them - no way to get this working.

    Then, I tried to write my custom implementation of GridLengthConverter and applying it as attribute as done before. This started working but it was clunky and unreliable (every time I changed the property value from xaml I got the error again; rebuilding project worked but this does not allowed me to change the property value while the application was running - which is supposed to be the expected behaviour on WPF).

    Finally, I simply changed how I was specifying property value in XAML and ended up with this:

    <local:MyUserControl
         Margin="20"
         IconColumnWidth="{Binding Source=50}" />
    

    I simply added a {Binding Source=myValue} where I needed to specify value for that property, having 'myValue' equals to desired value. This syntax works flawlessy even without specifying a TypeConverter (so I deleted my custom converter) and also recognises if I'm specifying a Pixel GridLength or a Star GridLength (proportional value, like "0.5*").

    I hope this will help someone else with the same issue.

    UPDATE

    After cloning source code from EldHasp's comment, I tried it out and found that even a clean solution (which does not give any error to others), it's giving me the same issue.

    Issue on clean solution

    At this point, I think this is an issue related to my Visual Studio installation. I'll try to uninstall and reinstall it, as soon I'll have a "code free" day (don't know when this will happen...)