【问题标题】:Defining list in xaml在 xaml 中定义列表
【发布时间】:2014-11-18 18:48:01
【问题描述】:

我正在制作自己的图形控件,它有数字列表

public class Figure
{
    public virtual void Render(Graph graph, GDI.Graphics graphics) { }
}

// was nested before, that's why here is @jnovo answer
public class Line : Figure { ... }
public class Plot : Figure { ... }
... // more figures

[ContentProperty("Figures")] // this doesn't help
public class Graph : FrameworkElement
{
    public IList<Figure> Figures { get; set; }
}

而且我在 xaml 中定义它时遇到问题:

<local:Graph>
    <local:Graph.Figures>
        <local:Line/> <!-- Property 'Figures' does not support values of type 'Line' -->
    </local:Graph.Figures>
</local:Graph>

如何解决?

【问题讨论】:

  • 将您的IList&lt;Figure&gt; 更改为List&lt;Figure&gt;,它现在可以工作了。
  • 虽然您在更新问题之前确实遇到了IList 的问题,但这不是主要问题 - 实际上还没有发生。恕我直言,您的编辑过于激进,没有反映原始问题。因此,在未来,请在编辑中投入更多精力 - 至少解释原始问题 - 或提出新问题。不管怎样,我很高兴你把它解决了:)

标签: c# wpf xaml


【解决方案1】:

来自XAML and Custom Classes for WPF in MSDN

您的自定义类不能是嵌套类。嵌套类及其常规 CLR 使用语法中的“点”会干扰其他 WPF 和/或 XAML 功能,例如附加属性。

所以,在Graph 类之外的命名空间中定义您的类。

【讨论】:

  • 嵌套类有几十个优点:没有命名空间冲突,访问非public方法。我不知道我是否准备好牺牲这一切。我看到我的问题标题不正确,而且这个问题很常见(12 等)。你知道是否有办法克服这个问题?仍然有嵌套类。
  • 对于命名空间冲突,您实际上可以嵌套命名空间或使用命名空间别名。可以说,如果您需要访问非公共方法,那么您的设计就有缺陷,除非您使用 protected 并从子类中访问它们。您也可以使用internal 进行程序集级访问,但我不鼓励这样做。
  • @Sinatr 顺便说一句,我不太同意你关于嵌套类有用性的说法。检查此SO question and answers 以获取它们的一些使用示例。底线:如果您需要在封闭类之外使用它们,则不应存在。
  • 我不认为存在设计问题,因为每个Figure 都需要来自Graph 的东西,而对于Graph 用户,我不想成为public。例如,计算边界、重绘图形或自动缩放图形到内容。 Graph 用户不应该看到任何 Graph.ZoomChangeGraph.GDIPen (例如使用图形的 RenderSize 从 gdi 之一创建 wpf 渐变画笔)。在基于Figure 的类中使用private 成员的能力真的很疯狂。但如果我想在 xaml 中使用它,我可能不得不牺牲所有这些。
  • 请查看最后的编辑。它不再嵌套,但问题仍然存在(看起来我的问题标题是正确的,这就是为什么我还没有提出新问题......)。
【解决方案2】:

将抽象IList 更改为ListObservableCollection 之类的类型应该是解决方案的一部分,因为我认为xaml 引擎不会仅仅决定哪种类型应该实现IList。列表的实例化也应该事先发生,我想在 xaml 中添加一个元素可能只是调用列表上的 Add 方法。

试试这是否适合你,是否适合我编译和运行。

// without DependencyProperty
public class Graph : FrameworkElement
{
    // Figures
    public List<Figure> Figures { get; set; }

    public Graph()
    {
        Figures = new List<Figure>();
    }
}

// with DependencyProperty
public class Graph : FrameworkElement
{
    // Figures
    private static readonly DependencyPropertyKey FiguresPropertyKey = DependencyProperty.RegisterReadOnly("Figures", typeof(ObservableCollection<Figure>), typeof(Graph), new FrameworkPropertyMetadata(new ObservableCollection<Figure>()));
    public static readonly DependencyProperty FiguresProperty = FiguresPropertyKey.DependencyProperty;
    public ObservableCollection<Figure> Figures { get { return (ObservableCollection<Figure>)GetValue(FiguresProperty); } }

    public Graph()
    {
        // explanation for this, see http://msdn.microsoft.com/en-us/library/aa970563%28v=vs.110%29.aspx
        SetValue(FiguresPropertyKey, new ObservableCollection<Figure>());
    }
}

【讨论】:

  • List 更改并且构造函数 catch 有效。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 2010-09-26
  • 2012-10-21
相关资源
最近更新 更多