F # Silverlight: использование PropertyPath или другого метода для обычного связывания столбцов - PullRequest
1 голос
/ 08 декабря 2010

Я пытаюсь заполнить значения автозаполнения динамически.Я получаю список кортежей 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])

не имеет особого смысла для меня ...

Ответы [ 2 ]

0 голосов
/ 08 декабря 2010

принимая это: 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

Полагаю, это правильное решение. Надеюсь, что «Мозги» (если бы это была опечатка или божественное вмешательство) также сработают, это намного проще.

0 голосов
/ 08 декабря 2010

Я на самом деле не знаю, но я бы попробовал

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

(например, поместить его в строку в кавычках), основываясь на прочтении этого:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...