F#WPF:处理列表框中的单击事件 [英] F# WPF: Handling click events in ListBox

查看:90
本文介绍了F#WPF:处理列表框中的单击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用F#和WPF创建一个简单的任务计划程序.它基本上只是一个任务列表,每个任务都有一个删除"按钮.处理列表之外的按钮单击不是问题-可以使用常规命令来处理.但是,要处理按钮,请单击列表中的 并不容易.我尝试使用此处描述的RelayCommand >,并将绑定路由到父级,但发件人对象始终为null(我希望它是集合中的任务对象).还尝试按照建议在此处附加属性,但无法使其正常工作.

I'm trying to create a simple task scheduler using F# and WPF. It's basically just a list of tasks where every task has a 'Delete' button. Handling button clicks outside of the list is not a problem -- this can be handled with a regular command. However handling a button click in the list item is not straightforward. I tried using RelayCommand described here with binding routed to parent, but the sender object is always null (I expected it to be the task object from the collection). Also tried attaching a property as recommended here, but couldn't make it work.

如何分配一个单击了删除"按钮即可获取任务对象的事件处理程序?

How do I assign an event handler that obtains the task object with clicked Delete button?

这是App.fs:

namespace ToDoApp

open System
open System.Windows
open System.Collections.ObjectModel
open System.Windows.Input
open FSharp.ViewModule
open FSharp.ViewModule.Validation
open FsXaml

type App = XAML<"App.xaml">
type MainView = XAML<"MainWindow.xaml">

type Task(str) = 
    member x.Description with get() = str

type MainViewModel() as self = 
    inherit ViewModelBase()  

    let tasks = new ObservableCollection<Task>()

    let addTaskCommand() =
        let descr = sprintf "Do something at %A" (DateTime.Now.AddMinutes(30.0))
        tasks.Add <| new Task(descr)

    member this.Tasks with get() = tasks
    member this.AddTask = this.Factory.CommandSync addTaskCommand

module main =
    [<STAThread>]
    [<EntryPoint>]
    let main argv =
        App().Run()

MainWindow.xaml:

MainWindow.xaml:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ToDoApp;assembly=ToDoApp"
    xmlns:fsxaml="http://github.com/fsprojects/FsXaml"
    Title="Simple ToDo app" Height="200" Width="400">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Name="newJobButton" Command="{Binding AddTask}" Width="100" Height="32" Margin="5, 5, 5, 5" HorizontalAlignment="Left">New task</Button>
        <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ListBox Name="lstBox" ItemsSource="{Binding Tasks}" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="80" />
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0" Content="{Binding Description}" Margin="5 5 0 0"/>
                            <!-- OnClick ??? -->
                            <Button Grid.Column="1">Delete</Button>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </ScrollViewer>
    </Grid>
</Window>

App.xaml太小了,因此这里不显示它.

App.xaml is trivial, so I'm not showing it here.

推荐答案

最好坚持使用命令:

ViewModel

member __.DelTask = 
    __.Factory.CommandSyncParam 
        (fun task -> tasks.Remove task |> ignore)

XAML

<Button Grid.Column="1" 
        Command="{Binding DataContext.DelTask, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
        CommandParameter="{Binding}"
        >Delete</Button>

在XAML中使用事件处理程序会导致难以测试和维护的意粉代码(即,关注点分离,将业务逻辑问题与UI问题分开处理).

Using event handlers in XAML results in spaghetti code which is harder to test and maintain (i.e. separation of concerns, handling business logic problems separately from UI problems).

这篇关于F#WPF:处理列表框中的单击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆