Home

Xaml string with bindings cannot be parsed

edited April 2022

I'm trying to write up a script that uses some WPF components for a UI. I haven't done so in a long time, but I know it has worked and it usually does. And so far it does if I just have plain xaml without bindings like so:

public class ViewModel : DependencyObject
{
    public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(nameof(Source), typeof(string), typeof(ViewModel));
    public static readonly DependencyProperty DestinationProperty = DependencyProperty.Register(nameof(Destination), typeof(string), typeof(ViewModel));

    public string Title => Util.CurrentQuery.Name;
    public string Source
    {
        get => (string)GetValue(SourceProperty);
        set => SetValue(SourceProperty, value);
    }
    public string Destination
    {
        get => (string)GetValue(DestinationProperty);
        set => SetValue(DestinationProperty, value);
    }
}

Window Initialize(ViewModel vm)
{
    var window = (Window)XamlServices.Parse($@"
<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
        Title='{vm.Title}'
        Width='800'
        Height='600'>
  <StackPanel>
    <StackPanel Orientation='Horizontal'>
        <Label Width='100'>Source:</Label>
        <TextBox Width='500' Text='{vm.Source}' />
        <Button>...</Button>
        <Button>Scan</Button>
    </StackPanel>
    <StackPanel Orientation='Horizontal'>
        <Label Width='100'>Destination:</Label>
        <TextBox Width='500' Text='{vm.Destination}' />
        <Button>...</Button>
    </StackPanel>
  </StackPanel>
</Window>
");
    window.DataContext = vm;
    return window;
}

However if I change the inserted text with bindings:

Window Initialize(ViewModel vm)
{
    var window = (Window)XamlServices.Parse($@"
<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
        Title='{{Binding Title}}'
        Width='800'
        Height='600'>
  <StackPanel>
    <StackPanel Orientation='Horizontal'>
        <Label Width='100'>Source:</Label>
        <TextBox Width='500' Text='{{Binding Source}}' />
        <Button>...</Button>
        <Button>Scan</Button>
    </StackPanel>
    <StackPanel Orientation='Horizontal'>
        <Label Width='100'>Destination:</Label>
        <TextBox Width='500' Text='{{Binding Destination}}' />
        <Button>...</Button>
    </StackPanel>
  </StackPanel>
</Window>
");
    window.DataContext = vm;
    return window;
}

I get the exception:

XamlObjectWriterException
Provide value on 'System.Windows.Data.Binding' threw an exception.
  - XamlParseException
    A 'Binding' cannot be set on the 'Text' property of type 'TextBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

The message doesn't make sense to me since there doesn't seem to be a problem running WPF, yet the error indicates that it cannot bind to the Window (System.Windows.Window) property, a Window is definitely a DependencyObject. It seems like there's some version mismatch somewhere or I haven't configured correctly. Is there something I'm missing?

LINQPad 7 Beta x64 v7.3.9
.NET 6.0.4

http://share.linqpad.net/7bgi9o.linq

Comments

  • p.s., This is not a LINQPad specific issue, I guess just XamlServices in general. Tried the same in a simple WPF app and failed with the same error.

  • Figured it out. Need to use System.Windows.Markup.XamlReader.Parse() instead of System.Xaml.XamlServices.Parse(). Was able to parse the xaml as expected. Theory is XamlServices is for general xaml and isn't fully WPF aware by default. XamlReader on the other hand is designed to work with WPF and is fully WPF-aware.

Sign In or Register to comment.