F# WPF脚本,点击按钮绘制图形
F# WPF script, draw graphics on button click
我正在尝试使用 F# 脚本,我只想通过单击按钮在空白 Windows 表单上画线。希望你能看到我在这里尝试做的事情:
open System.Drawing
open System.Windows.Forms
let form = new Form(Width = 400, Height = 400, Text = "draw test")
let panel = new FlowLayoutPanel()
form.Controls.Add(panel)
let paint(e : PaintEventArgs) =
let pen = new Pen(Color.Black);
e.Graphics.DrawLine(pen, new PointF(100.0f, 100.0f), new PointF(200.0f, 200.0f))
let button = new Button()
button.Text <- "Click to draw"
button.AutoSize <- true
button.Click.Add(fun _ -> form.Paint.Add(paint)) // <- does not draw a line on click
panel.Controls.Add(button)
//form.Paint.Add(paint) <- here, if uncommented, it will draw a line when the script is run
form.Show()
如果我在 form.Show()
上面取消注释 form.Paint.Add(paint)
,那么它当然会在表单上绘制,但我正在尝试通过单击按钮来完成。我不太清楚如何在这样的脚本中实现这一点,我一直在四处寻找 F# 中的类似示例。任何帮助将不胜感激。
如果您在第一次绘制表单之前添加 Paint 事件处理程序,那么它将使用该处理程序进行绘制。
如果您在之后添加它,您需要确保表单随后会自行重绘。例如,您可以在其上调用 Refresh
或 Invalidate
。
例如:
button.Click.Add(fun _ -> form.Paint.Add(paint); form.Invalidate())
原来是编辑,我把它移到了答案部分:
好的,所以我对 WPF 和 Winforms 之间的区别感到困惑,因为我看到这些术语在不同的地方一起使用......@Asik 为 Winforms 添加了一个答案,但在这里我一起拍打基于几个 FSharp Snippets(以及几个 Google 搜索)的专门用于 WPF 的工作 .fsx 脚本,如果需要也可以编译。我会根据需要或请求更新此内容。另外,要指出的是,这背后的全部动机是能够通过 FSI 快速测试绘图图形。
#r @"PresentationCore"
#r @"PresentationFramework"
#r @"WindowsBase"
#r @"System.Xaml"
#r @"UIAutomationTypes"
open System
open System.Windows
open System.Windows.Media
open System.Windows.Shapes
open System.Windows.Controls
let window = Window(Height = 400.0, Width = 400.0)
window.Title <- "Draw test"
let stackPanel = StackPanel()
window.Content <- stackPanel
stackPanel.Orientation <- Orientation.Vertical
let button1 = Button()
button1.Content <- "Click me to draw a blue ellipse"
stackPanel.Children.Add button1
let button2 = Button()
button2.Content <- "Click me to draw a red ellipse"
stackPanel.Children.Add button2
let clearButton = Button()
clearButton.Content <- "Click me to clear the canvas"
stackPanel.Children.Add clearButton
let canvas = Canvas()
canvas.Width <- window.Width
canvas.Height <- window.Height
stackPanel.Children.Add canvas
let buildEllipse height width fill stroke =
let ellipse = Ellipse()
ellipse.Height <- height
ellipse.Width <- width
ellipse.Fill <- fill
ellipse.Stroke <- stroke
ellipse
let ellipse1 = buildEllipse 100.0 200.0 Brushes.Aqua Brushes.Black
Canvas.SetLeft(ellipse1, canvas.Width / 10.0) //messy, will fix at some point!
Canvas.SetTop(ellipse1, canvas.Height / 10.0)
let ellipse2 = buildEllipse 200.0 100.0 Brushes.Red Brushes.DarkViolet
Canvas.SetLeft(ellipse2, canvas.Width / 4.0)
Canvas.SetTop(ellipse2, canvas.Height / 5.0)
let addEllipseToCanvas (canvas:Canvas) (ellipse:Ellipse) =
match canvas.Children with
| c when c.Contains ellipse ->
canvas.Children.Remove ellipse
canvas.Children.Add(ellipse) |> ignore //needs to be removed and readded or the canvas complains
| _ ->
canvas.Children.Add(ellipse) |> ignore
button1.Click.Add(fun _ -> addEllipseToCanvas canvas ellipse1)
button2.Click.Add(fun _ -> addEllipseToCanvas canvas ellipse2)
clearButton.Click.Add(fun _ -> canvas.Children.Clear())
#if INTERACTIVE
window.Show()
#else
[<EntryPoint; STAThread>]
let main argv =
let app = new Application()
app.Run(window)
#endif
我正在尝试使用 F# 脚本,我只想通过单击按钮在空白 Windows 表单上画线。希望你能看到我在这里尝试做的事情:
open System.Drawing
open System.Windows.Forms
let form = new Form(Width = 400, Height = 400, Text = "draw test")
let panel = new FlowLayoutPanel()
form.Controls.Add(panel)
let paint(e : PaintEventArgs) =
let pen = new Pen(Color.Black);
e.Graphics.DrawLine(pen, new PointF(100.0f, 100.0f), new PointF(200.0f, 200.0f))
let button = new Button()
button.Text <- "Click to draw"
button.AutoSize <- true
button.Click.Add(fun _ -> form.Paint.Add(paint)) // <- does not draw a line on click
panel.Controls.Add(button)
//form.Paint.Add(paint) <- here, if uncommented, it will draw a line when the script is run
form.Show()
如果我在 form.Show()
上面取消注释 form.Paint.Add(paint)
,那么它当然会在表单上绘制,但我正在尝试通过单击按钮来完成。我不太清楚如何在这样的脚本中实现这一点,我一直在四处寻找 F# 中的类似示例。任何帮助将不胜感激。
如果您在第一次绘制表单之前添加 Paint 事件处理程序,那么它将使用该处理程序进行绘制。
如果您在之后添加它,您需要确保表单随后会自行重绘。例如,您可以在其上调用 Refresh
或 Invalidate
。
例如:
button.Click.Add(fun _ -> form.Paint.Add(paint); form.Invalidate())
原来是编辑,我把它移到了答案部分:
好的,所以我对 WPF 和 Winforms 之间的区别感到困惑,因为我看到这些术语在不同的地方一起使用......@Asik 为 Winforms 添加了一个答案,但在这里我一起拍打基于几个 FSharp Snippets(以及几个 Google 搜索)的专门用于 WPF 的工作 .fsx 脚本,如果需要也可以编译。我会根据需要或请求更新此内容。另外,要指出的是,这背后的全部动机是能够通过 FSI 快速测试绘图图形。
#r @"PresentationCore"
#r @"PresentationFramework"
#r @"WindowsBase"
#r @"System.Xaml"
#r @"UIAutomationTypes"
open System
open System.Windows
open System.Windows.Media
open System.Windows.Shapes
open System.Windows.Controls
let window = Window(Height = 400.0, Width = 400.0)
window.Title <- "Draw test"
let stackPanel = StackPanel()
window.Content <- stackPanel
stackPanel.Orientation <- Orientation.Vertical
let button1 = Button()
button1.Content <- "Click me to draw a blue ellipse"
stackPanel.Children.Add button1
let button2 = Button()
button2.Content <- "Click me to draw a red ellipse"
stackPanel.Children.Add button2
let clearButton = Button()
clearButton.Content <- "Click me to clear the canvas"
stackPanel.Children.Add clearButton
let canvas = Canvas()
canvas.Width <- window.Width
canvas.Height <- window.Height
stackPanel.Children.Add canvas
let buildEllipse height width fill stroke =
let ellipse = Ellipse()
ellipse.Height <- height
ellipse.Width <- width
ellipse.Fill <- fill
ellipse.Stroke <- stroke
ellipse
let ellipse1 = buildEllipse 100.0 200.0 Brushes.Aqua Brushes.Black
Canvas.SetLeft(ellipse1, canvas.Width / 10.0) //messy, will fix at some point!
Canvas.SetTop(ellipse1, canvas.Height / 10.0)
let ellipse2 = buildEllipse 200.0 100.0 Brushes.Red Brushes.DarkViolet
Canvas.SetLeft(ellipse2, canvas.Width / 4.0)
Canvas.SetTop(ellipse2, canvas.Height / 5.0)
let addEllipseToCanvas (canvas:Canvas) (ellipse:Ellipse) =
match canvas.Children with
| c when c.Contains ellipse ->
canvas.Children.Remove ellipse
canvas.Children.Add(ellipse) |> ignore //needs to be removed and readded or the canvas complains
| _ ->
canvas.Children.Add(ellipse) |> ignore
button1.Click.Add(fun _ -> addEllipseToCanvas canvas ellipse1)
button2.Click.Add(fun _ -> addEllipseToCanvas canvas ellipse2)
clearButton.Click.Add(fun _ -> canvas.Children.Clear())
#if INTERACTIVE
window.Show()
#else
[<EntryPoint; STAThread>]
let main argv =
let app = new Application()
app.Run(window)
#endif