【问题标题】:The specified value cannot be assigned to the collection无法将指定的值分配给集合
【发布时间】:2015-07-19 02:31:44
【问题描述】:

编辑

这困扰了我将近一年。我会更新答案并添加赏金。

我有自定义控件,它具有依赖属性

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 是所有图形的基类:

public abstract class Figure { ... }

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

现在看下面的截图来看看问题所在:有时(在其他地方对 xaml 进行更改后)设计者对此感到疯狂并停止渲染整个窗口,抛出异常,而代码编译和运行没有问题。我可以关闭此 xaml(设计器)并再次打开它以使问题消失。但它总是会再次出现。

问题:我这边有什么问题吗?缺少属性?错误用法?我该如何解决这个问题?


老问题

糟糕的情况。

我有 2 个UserControl。在这两个手工控制Graph 中使用。 Graph 具有属性 Figures 以指定 List&lt;Figure&gt;。以Figure为基数的数字有几十个。

在一个UserControl 中它工作正常,在另一个抛出异常

无法将指定的值分配给集合。以下类型应为:“Figure”。

我看不出可能导致问题的差异。


这是一张有问题的截图


这是一个工作

尽管有错误项目编译并运行,但如果我需要对有问题的UserControl 进行修改,那么它不会显示任何内容(说“无效标记”)。图表几乎相同,所有8 错误仅针对一个UserControl 显示。

我该怎么办?如何解决此类错误?我(完全)排除了Graph 的任何问题,因为它运行时没有任何问题,并且对于另一个UserControl 也没有问题。 Visual Studio 设计器问题?使用 2013 Express for Windows 桌面。

【问题讨论】:

  • 控制是否与使用控制在同一个项目中?如果不是,如何添加参考?
  • 你试过用 IList 代替 List 吗?此外,您可以尝试使用FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender) 而不是普通的PropertyMetadata 作为依赖属性,然后您可以摆脱整个InvalidateVisual 代码。

标签: c# wpf xaml


【解决方案1】:

确实,视觉设计师无法识别来自Figure 的继承。一种解决方案是使用 IList 作为接口类型:

    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>()));

这可能看起来有点奇怪(因为你放弃了类型安全性)。但是仔细看看 WPF 类。他们都这样做(很可能有充分的理由)。或者 WPF 甚至创建像 PathFigureCollection 这样实现 IListIList&lt;PathFigure&gt; 的集合类。

【讨论】:

  • 我可能是错的,但根据我的经验(我开发了一些自定义控件),使用 IList 而不是 IList&lt;&gt; 的一个很好的原因是您可以实例化 ListCollectionView IList,但不适用于 IList&lt;&gt;。一旦你手中有了ICollectionView,你就可以使用它而不是集合本身来修改所述集合。
  • 下次出现问题(我无法在需要时重现它,但它迟早会弹出)我会尝试IList。您的回答也帮助我看到了一个可能的问题——我没有使用PropertyMetadata 中的属性的默认值(在我的情况下应该是new List&lt;Figure&gt;()),而是在构造函数中设置。也许是null 值导致问题的原因是什么?无论如何也会尝试一下。可惜赏金将在 4 小时后到期。我真的希望你的答案是正确的。
  • 错误再次弹出。我已经做到了IList 并且错误消失了。除非关闭/打开xaml,否则它从未消失过。确定将其标记为答案,谢谢!
【解决方案2】:

关闭项目,重新启动 VS 并重新打开它。它仍然列出错误吗? visual studio 似乎经常报告“幻像错误”,但如果您关闭并重新启动等,它们通常会消失。

【讨论】:

  • 幻像错误?重新启动后(项目已编译),一开始没有错误。更改后(需要重新编译)出现错误。这一次,另一个UserControl 有类似的错误(这次是 16 个),第一个没有显示一个错误。真的吗?
  • 和另一个my problem一起让我觉得我必须重新安装VS、windows、格式化HDD或购买新PC。
  • 是的,我同意。无论如何,请将此标记为已回答。
  • 我会的,但问题仍然 ;).
  • 只是我的意见,但我会停止使用可视化编辑器。它没有提供任何价值。它几乎不会按照程序在程序中出现的方式呈现页面。加载需要很长时间。它会在您的错误列表中产生幻像错误。工具箱的东西需要永远加载。即使是拖放支持也从未真正将元素放置在您想要的位置。您需要的一切都在 XAML 中。所见即所得会很好,每个人都想要它,但它永远不会起作用。坦率地说,MS 将其设为默认设置让我很恼火。
【解决方案3】:

如果自定义控件在同一个解决方案或项目中,Visual Studio 会构建它(当它认为有必要时),以便它可以在设计器中使用该控件。

有时此构建/缓存版本与代码文件不同步,这会导致 Xaml 解析器/语法检查器混淆并显示那些波浪状的红线。

我已经成功关闭并重新打开了所有使用该控件的设计师,但继续这样做很烦人。根据我的经验,最可靠的解决方案是将控件移动到单独的解决方案和项目中,并设置对 dll 的“正确”引用。

【讨论】:

  • 这听起来……令人沮丧。每个 wpf 解决方案拥有这样的带有控件的项目是否就足够了,还是您的意思是 另一个解决方案
  • 如果它在同一个解决方案的另一个项目中,问题仍然存在。所以需要一个单独的解决方案。只要包含控件的项目未在 Visual Studio 中加载,它似乎就可以工作。请注意,这完全来自经验,我在推理或理解方式和内容方面可能是错误的,但这对我有用。试试吧
  • 谢谢。如果没有其他选择,我会尝试。或者也许只是忍受它(因为每次创建 2 个解决方案只是.. kek)。
  • 如果有什么安慰的话:自定义控件意味着可以重复使用,因此将它们放在自己的解决方案中是有意义的。 (我仍然认为应该可以在同一个解决方案中使用控件而不会出现这些问题)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2018-03-14
  • 2017-12-10
  • 2022-06-14
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
相关资源
最近更新 更多