【问题标题】:F# Silverlight: using PropertyPath or other method to bind columns ordinallyF# Silverlight:使用 PropertyPath 或其他方法按顺序绑定列
【发布时间】:2010-12-07 21:53:50
【问题描述】:

我正在尝试动态填充自动完成的值。我得到一个 SearchResult 元组列表,其中每个元组的第一个字符串是 KEY,字符串列表是需要在每列显示的显示文本。假设任何 SearchResult 列表中的所有行都将在显示文本列表中包含相同数量的项目。我真的很希望能够通过序数绑定到显示文本列表的值...

一个简化的示例将采用如下数据:

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

并显示:

MSFT.OQ         Microsoft       Nasdaq
GOOG.OQ         Google          Nasdaq

但我看到类似:

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

整个列表都在每一列中结束,所以我认为我的绑定已关闭。

我的示例代码(试图从更复杂的模型中简化):

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

谢谢...


令人惊讶的是(至少对我而言)这些返回相同的结果:

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

对我来说没有多大意义......

【问题讨论】:

    标签: silverlight xaml binding f#


    【解决方案1】:

    我真的不知道,但我会尝试

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

    (例如,将其放在带引号的字符串中),基于阅读以下内容:

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

    【讨论】:

    • 不幸的是,它没有用。我昨天早些时候阅读了该页面并尝试了类似的内容(昨天我在赶火车时没有详细查看您的帖子),但也没有用。它显示一个大约四分之一大小的 3 x 4 网格,其中没有文本。如果该类(属性路径)有更好的文档或源 - 那会很好 - 但它似乎不起作用,至少在 F# 中并绑定到索引器以进行数据网格绑定。
    【解决方案2】:

    采用这个: http://www.scottlogic.co.uk/blog/colin/2009/04/binding-a-silverlight-datagrid-to-dynamic-data-via-idictionary/

    工作:

    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()
    

    并在我的代码中将绑定替换为

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

    我想这是一个不错的解决方案。希望 Brains(这是一个错字还是上帝的干预)也能正常工作,它更直接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 2010-12-08
      • 2012-05-01
      相关资源
      最近更新 更多