Catastrophic failure in xaml binding

1

I am developing Windows 10 Universal App. I have code below:

xaml:

<Page
    x:Class="MyProject.BlankPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyProject"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
>
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Background="Purple"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Rectangle Fill="Red" Width="50" Height="50"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Page>

and code behind:

namespace MyProject
{
    public sealed partial class BlankPage1 : Page
    {
        public BlankPage1()
        {
            DataContext =
                new[]
                {
                    new { X = 50.0, Y = 100.0 },
                    new { X = 220.0, Y = 170.0 }
                };
            InitializeComponent();
        }
    }
}

Unfortunatelly, the rectangles does not show in the window. I am getting compilation error:

Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))

Assigning to Canvas coordinates static numbers in xaml works as expected.

Why error occurs and code does not work?

c#
xaml
canvas
windows-10
itemscontrol
asked on Stack Overflow Oct 22, 2015 by pt12lol • edited Oct 22, 2015 by pt12lol

1 Answer

1

I just stumbled upon this issue myself, while building a Universal Windows Platform app.

Did some googling, found this article.

It was very helpful. I copied his SetterValueBindingHelper class into my own project. After that, I made 1 adjustment, because

type = System.Type.GetType(item.Type).GetTypeInfo();

gave an exception when you do Type="Canvas" in the XAML binding. It first tries to find the class Canvas in the current assembly. This returns null, and then it calls .GetTypeInfo() throwing a NullReferenceException.

Implemented C# 6.0's new Null-Conditional Operator on it, and that solved this issue. The code immediately after checks if type is null, and then goes through all loaded assemblies to find the Canvas.

type = System.Type.GetType(item.Type)?.GetTypeInfo();

His second usage example is oddly specifically related to using it with a Canvas element.

Another example from my Project VisualDesigner:

Here's my final XAML, based on his example:

<ItemsControl Grid.Column="1" ItemsSource="{Binding CanvasItems}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="helpers:SetterValueBindingHelper.PropertyBinding">
                <Setter.Value>
                    <helpers:SetterValueBindingHelper>
                        <helpers:SetterValueBindingHelper Type="Canvas" Property="Left" Binding="{Binding WindowX, Mode=TwoWay}" />
                        <helpers:SetterValueBindingHelper Type="Canvas" Property="Top" Binding="{Binding WindowY, Mode=TwoWay}" />
                    </helpers:SetterValueBindingHelper>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <applicationwindow:ApplicationWindow Width="{Binding WindowWidth}" Height="{Binding WindowHeight}" DataContext="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

helpers: refers to the namespace the SetterValueBindingHelper is in. ApplicationWindow in my case is a custom UserControl. CanvasItems is an ObservableCollection<ApplicationWindowViewModel>, and this is my ApplicationWindowViewModel:

[ImplementPropertyChanged]
public class ApplicationWindowViewModel : ViewModelBase
{
    public string Title { get; set; }

    public double WindowX { get; set; } = 10;

    public double WindowY { get; set; } = 10;

    public int WindowWidth { get; set; } = 300;

    public int WindowHeight { get; set; } = 200;
}

In this example I use Fody.PropertyChanged to handle the property changed events on the X/Y/Width/Height properties, if you're not using this package, don't forget to implement your own PropertyChanged event handlers, etc.

answered on Stack Overflow Mar 6, 2016 by René Sackers

User contributions licensed under CC BY-SA 3.0