Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The specified value cannot be assigned to the collection

Tags:

c#

wpf

xaml

Edit

This bugs me for an almost year. I'll update the answer and add bounty.

I've custom control, which has dependency property

public class Graph : Control
{
    public List<Figure> Figures
    {
        get { return (List<Figure>)GetValue(FiguresProperty); }
        set { SetValue(FiguresProperty, value); }
    }
    public static readonly DependencyProperty FiguresProperty =
        DependencyProperty.Register("Figures", typeof(List<Figure>), typeof(Graph),
        new PropertyMetadata((d, e) => ((Graph)d).InvalidateVisual()));
    ...
}

Figure is the base class for all figures:

public abstract class Figure { ... }

public class LineFigure : Figure { ... }
public class XGridFigure : Figure { ... }
public class YGridFigure : Figure { ... }
...

Now look at screenshots below to see the problem: sometimes (after doing a change to xaml in other place) designer goes crazy about it and stop rendering the whole window, throwing exceptions, while code compiles and runs without problem. I can close this xaml (designer) and open it again to make problem go away. But it always reappears.

Question: is there something wrong on my side? Missing attribute? Wrong usage? How can I fix that problem?


Old question

Ugly situation.

I have 2 UserControl. In both hand-made control Graph is used. Graph has property Figures to specify List<Figure>. There are dozens of figures which have Figure as base.

In one UserControl it works fine, in other throws exception

The specified value cannot be assigned to the collection. The following type was expected: "Figure".

And I fail to see a difference what could cause a problem.


Here is problematic one screenshot


And here is working one

Despite of errors project compiles and runs, but if I need to do modification to problematic UserControl, then it's not showing any content (says "Invalid Markup"). Graphs are nearly the same, all 8 errors are shown for to just one UserControl.

What should I do? How to troubleshoot such errors? I exclude (completely) any problem with Graph because it runs without a single problem AND it works without problem for another UserControl. Visual Studio designer problem? Using 2013 Express for Windows Desktop.

like image 384
Sinatr Avatar asked Oct 28 '14 10:10

Sinatr


3 Answers

Indeed the visual designer does not recognize the inheritance from Figure. One solution is to use IList as the Interface type:

    public IList Figures
    {
        get
        {
            return (IList)GetValue (FiguresProperty);
        }
        set
        {
            SetValue (FiguresProperty, value);
        }
    }

    public static readonly DependencyProperty FiguresProperty =
        DependencyProperty.Register ("Figures", typeof (IList), typeof (Graph), new PropertyMetadata (new List<object>()));

That might look like a bit strange (because you give up type safetyness). But have a closer look at the WPF classes. They all do it that way (most likely for good reasons). Or WPF even creates collection classes like PathFigureCollection that implement both IList and IList<PathFigure>.

like image 73
gomi42 Avatar answered Nov 09 '22 08:11

gomi42


close the project, restart VS and reopen it. does it still list the errors? visual studio often seems to report "phantom errors", but they usually go away if you close and restart etc.

like image 35
Theodosius Von Richthofen Avatar answered Nov 09 '22 09:11

Theodosius Von Richthofen


If the custom control is in the same solution or project, Visual Studio builds it (when it considers it necessary) so it can use the control in the designer.

Sometimes this built/cached version gets out of sync with the code files which causes the Xaml parser/syntax checker to get confused and display those wavy red lines.

I have had success with closing and reopening all designers that use the control but that is pretty annoying to keep on doing. In my experience the most reliable solution is to move the control into a separate solution and project and set a 'proper' reference to the dll.

like image 42
Emond Avatar answered Nov 09 '22 08:11

Emond