2016-12-18 2 views
4

F # 및 WPF를 사용하여 간단한 작업 스케줄러를 만들려고합니다. 기본적으로 모든 작업에 '삭제'버튼이있는 작업의 목록입니다. 목록 외부에서 버튼 클릭을 처리하는 것은 문제가되지 않습니다. 이것은 일반적인 명령으로 처리 할 수 ​​있습니다. 그러나 단추를 처리 에서 목록 항목은 간단하지 않습니다. 나는 RelayCommand를 사용하여 부모에게 라우팅 된 바인딩으로 here을 설명했지만 송신자 객체는 항상 null입니다 (컬렉션의 작업 객체라고 기대했습니다). 또한 권장 속성 인 here을 첨부하려고했지만 작동하지 못했습니다.F # WPF : ListBox의 클릭 이벤트 처리

삭제 단추를 클릭하여 작업 개체를 가져 오는 이벤트 처리기를 어떻게 할당합니까? 여기

는 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 :

<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 사소한, 그래서 여기에 그것을 보여주는 아니에요.

답변

4

이 명령에 충실하는 것이 좋습니다 :

뷰 모델

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

에게 테스트 열심히하고 있습니다 스파게티 코드에서 XAML 결과에 이벤트 핸들러를 사용하여 XAML

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

유지 (즉, 관심사 분리, 비즈니스 논리 문제 처리 UI 문제와 달리).

+1

매력처럼 작동합니다! 고맙습니다! –