WPF和自定义渲染

时间:2014-02-18 23:12:57

标签: wpf xaml f#

我在F#和WPF中尝试一个非常简单的例子。我想在Canvas上覆盖OnRender。 我这样做了:

namespace App

open ...

type public MyRender =
  class
    inherit FrameworkElement

    new() = { inherit FrameworkElement() }

    override this.OnRender(dc:DrawingContext) =
      dc.DrawRectangle(Brushes.DarkGray, null, new Rect(0.0, 0.0, 200.0, 80.0))
      let text = new FormattedText("Hello World!", 
                                   CultureInfo.CurrentUICulture,
                                   FlowDirection.LeftToRight,
                                   new Typeface("Tahoma"), 20.0, Brushes.White)
      dc.DrawText(text, new Point(30.0, 25.0))
      dc.DrawEllipse(new SolidColorBrush(Colors.Black), 
                     new Pen(Brushes.Blue, 10.0), 
                     new Point(256.0, 256.0), 80.0, 30.0)
      base.OnRender(dc)
  end

module Main = 
  type MainWindow = XAML<"MainWindow.xaml">
  let loadWindow() =
    let window = MainWindow()
    window.Root

  [<;STAThread>;]
  (new Application()).Run(loadWindow()) |> ignore

在XAML文件中:

<Window x:Class="System.Windows.Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              mc:Ignorable="d"
        xmlns:wf="clr-namespace:App"
        Title="" Height="450" Width="500">
        <Canvas Height="400" Width="400">
        <wf:MyRender Width="300" Height="300"/>
        </Canvas>
</Window>

该应用程序的名称是App.fs. XAML一直告诉我在App命名空间中找不到MyRender。我无法理解为什么或我能做些什么来解决它。有人可以启发我吗?

提前致谢。

[编辑]我已使用Tomas Petricek的建议编辑了代码。我还将MyRender从FrameworkElement继承并将其放入Canvas中。现在,VS2013中的XAML窗口显示了MyRender元素。但是我仍然遇到无法创建未知类型'{clr-namespace:App} MyRender'的运行时异常。

现在问题似乎是我需要将ws:namespace指向当前程序集。 关于如何做到这一点的任何想法?

1 个答案:

答案 0 :(得分:1)

假设您发布的App.fs文件中没有其他内容,问题可能是该文件(隐式)编译为名为App模块而不是名为App namespace (模块显示为静态类,因此您的MyRender实际上是嵌套类。)

尝试将namespace声明添加到顶部:

namespace App

type MyRender() =
  inherit Canvas()
  override this.OnRender(dc:DrawingContext) =
    (...)

type MainWindow = XAML<"MainWindow.xaml">

module Main = 
  let loadWindow() =
    let window = MainWindow()
    window.Root

  [<STAThread>]
  do (new Application()).Run(loadWindow()) |> ignore

我还略微简化了MyRender类的定义,并添加了用于保存入口点代码的模块。请注意,我实际上没有尝试过这个 - 所以没有保证!