2010-12-07 23 views
1

J'essaie de remplir dynamiquement les valeurs d'une saisie semi-automatique. Je reçois une liste de tuples SearchResult, où par tuple la première chaîne est la clé et la liste des chaînes est le texte à afficher par colonne. L'hypothèse est que de n'importe quelle liste de SearchResult toutes les lignes contiendront le même nombre d'éléments dans la liste de texte d'affichage. Je voudrais vraiment être capable de se lier aux valeurs de la liste de textes d'affichage par ordinal ...F # Silverlight: utilisation de PropertyPath ou d'une autre méthode pour lier les colonnes en général

un exemple simplifié prendrait des données comme ceci:

[ 
    ("MSFT.OQ", ["MSFT.OQ"; "Microsoft"; "Nasdaq"]) ; 
    ("GOOG.OQ", ["GOOG.OQ"; "Google"; "Nasdaq"]); 
] 

et affichage:

MSFT.OQ   Microsoft  Nasdaq 
GOOG.OQ   Google   Nasdaq 

mais je vois quelque chose comme:

["MSFT.OQ"; "Microsoft"; "Nasdaq"]  ["MSFT.OQ"; "Microsoft"; "Nasdaq"] ["MSFT.OQ"; "Microsoft"; "Nasdaq"] 
["GOOG.OQ"; "Google"; "Nasdaq"]  ["GOOG.OQ"; "Google"; "Nasdaq"]  ["GOOG.OQ"; "Google"; "Nasdaq"] 

La liste complète se termine dans chaque colonne, donc je pense que ma liaison est éteinte.

Mon exemple de code (a tenté d'être simplifié à partir d'un modèle plus complexe):

type SearchResult = (string * string list) 

type Template() as this = 
    inherit Page 

    [<DefaultValue>] 
    val mutable acbTickerSearch : AutoCompleteBox 

    do 
     this.acbTickerSearch = this ? acbTickerSearch 
     this.display Some(this.getSampleResults()) 

    member private this.getSampleResults() = 
     [ 
      ("MSFT.OQ", ["MSFT.OQ"; "Microsoft"; "Nasdaq"]) ; 
      ("GOOG.OQ", ["GOOG.OQ"; "Google"; "Nasdaq"]); 
      ("IBM", ["IBM"; "International Business Machines"; "NYSE"]); 
      ("AKAM.OQ", ["AKAM.OQ"; "Akamai"; "Nasdaq"]); 
     ] 

    member this.display (results: SearchResult list option) = 
     let build(result: SearchResult) = 
      // if we haven't built the bindings yet lets do so 
      if this.tickerSearchDataGrid = null then 
       // create a grid 
       this.tickerSearchDataGrid <- new DataGrid() 
       this.tickerSearchDataGrid.AutoGenerateColumns <- false 

       let addColumn i (item: string) = 
        let col = new DataGridTextColumn() 
        let binding = System.Windows.Data.Binding() 

        // LOOK HERE: attempting to bind to an indexer... not working so well,, 
        binding.Path <- PropertyPath([i]) 

        col.Binding <- binding 
        this.tickerSearchDataGrid.Columns.Add(col) 
        i + 1 

       result 
        // the second portion of the tuple, is a list that 
        // needs to be displayed, wach item in its own column 
        |> snd 
        // should probably be List.iteri 
        |> List.fold addColumn 0 
        // don't need this with List.iteri 
        |> ignore 

     let displayResults (resultLst: SearchResult list) = 
      // create a list of lists, throwing away the "key" portion of the tuple 
      // potentially a bug I need toget around... 
      let lst = 
       resultLst 
        |> List.map (fun (r: SearchResult) -> snd r) 

      // bind to the data source 
      this.tickerSearchDataGrid.ItemsSource <- lst 
      this.tickerSearchDataGrid.HeadersVisibility <- DataGridHeadersVisibility.None 
      this.acbTickerSearch.ItemsSource <- [this.tickerSearchDataGrid] 
      this.acbTickerSearch.IsDropDownOpen <- true 

     match results with 
     | None ->() 
     | Some r -> 
      // set the number of columns based on the results, 
      // assume all tuples will have an equal number of values, 
      // we only need the head to determine the columns then 
      build <| List.head r 

      // bind the results 
      displayResults r 

Merci ...


suprisingly (pour moi au moins) ceux-ci reviennent les mêmes résultats :

binding.Path <- PropertyPath([]) 
    binding.Path <- PropertyPath("") 
    binding.Path <- PropertyPath([0].[0]) 

ne pas me faire beaucoup de sens ...

Répondre

0

adoptant ceci: http://www.scottlogic.co.uk/blog/colin/2009/04/binding-a-silverlight-datagrid-to-dynamic-data-via-idictionary/

travaillé:

type RowIndexConverter() = 
    interface IValueConverter with 
     member this.Convert(value, targetType, parameter, culture) = 
      let row = value :?> string list ; 

      let index: int = parameter :?> int; 
      row.[index] :> obj; 

     member this.ConvertBack(value, targetType, parameter, culture) = raise <| NotImplementedException() 

et dans mon code remplaçons la liaison avec

let binding = System.Windows.Data.Binding() 
binding.Path <- PropertyPath([]) 
binding.Converter <- RowIndexConverter() 
binding.ConverterParameter <- i 

Je gu C'est une bonne solution. Espérons que Brains (était-ce une faute de frappe ou une intervention divine) fonctionnera aussi, c'est beaucoup plus simple.

0

Je ne sais pas vraiment, mais je voudrais essayer

binding.Path <- PropertyPath(sprintf "[%d]" i) 

(par exemple le mettre dans une chaîne entre guillemets), basée sur la lecture de ceci:

http://msdn.microsoft.com/en-us/library/cc645024%28VS.95%29.aspx

+0

Malheureusement, cela n'a pas fonctionné. J'ai lu cette page plus tôt et j'ai essayé quelque chose de similaire (je n'ai pas regardé votre poste en détail hier car je courais pour attraper un train) et ça n'a pas marché non plus. Il affiche une petite grille de 3 sur 4 de la taille d'un quart, qui n'a pas de texte. S'il y avait une meilleure documentation OU source pour cette classe (chemin de la propriété) - ce serait sympa - mais cela ne semble pas fonctionner, au moins dans F # et se lier aux indexeurs pour les liaisons de données. – akaphenom