【问题标题】:Fluent WPF API for inherited properties用于继承属性的 Fluent WPF API
【发布时间】:2012-02-17 11:53:45
【问题描述】:

有时我会有一些 WPF C# 代码,我想以“流利”的方式编写。

例如,我可能想设置一个包含ScrollViewerWindow

new Window()
    .SetContent(
        new ScrollViewer()
            .SetContent(
                ...))

为了实现这种 API,我一直在使用以下扩展方法:

static class FluentScrollViewer
{
    public static ScrollViewer SetContent(this ScrollViewer obj, object val)
    { obj.Content = val; return obj; }
}

static class FluentWindow
{
    public static Window SetContent(this Window obj, object val)
    { obj.Content = val; return obj; }
}

现在,WindowScrollViewer 都从 ContentControl 继承了 Content 属性。然而,我不得不为每个类分别定义 SetContent 扩展方法。

如果我尝试这样做:

static class FluentContentControl
{
    public static ContentControl SetContent(this ContentControl obj, object val)
    { obj.Content = val; return obj; }
}

然后像这样使用它:

new Window().SetContent(...)

SetContent 方法当然不会返回 Window

有没有办法在 ContentControl 之上定义 SetContent 并让它做“正确的事情”以避免定义许多除了类型之外相似的单独的专门方法?

【问题讨论】:

标签: c# wpf fluent fluent-interface


【解决方案1】:

我认为当您创建新控件时不会有太大收获,因为您也可以使用initializers

new Window() {
    Content = new ScrollViewer() { Content = ... }
};

【讨论】:

  • +1 初始化器比一长串流畅的调用更具可读性。
  • 然而,初始化器无助于设置现有对象的属性。
  • @dharmatech:正如我所说,这仅适用于创建新控件。我的回答只是对这种特殊情况的补充,因为 Piotr 已经回答了如何使方法通用。
【解决方案2】:

你可以使用泛型:

public static TControl SetContent<TControl>(this TControl obj, object val)
where TControl : ContentControl
{ 
    obj.Content = val; 
    return obj; 
}

【讨论】:

  • 谢谢彼得!完美运行!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多