2009-05-19 65 views
0

我的場景: wpf表單有一個文本框和一個wpf工具箱datagrid。 在文本框中輸入文本時,我的服務將返回IEnumerable<TranslationItem>項目。我想讓我的數據網格顯示這個服務的結果。無法將我的頭圍繞wpf數據綁定

我試過用google搜索,但是我無法得到正面或反面。我只是開始學習WPF,大部分使用的術語都沒有涉及到。
我收集的是我應該把我的服務的結果放在ObservableCollection中,而不是汗水。 但是,然後我想以某種方式將其綁定到我的數據網格。我怎樣才能做到這一點?網格如何知道要生成哪些列?

回答

0

您將網格的DataSource(甚至是DataContext)設置爲您的Observable集合。

我不熟悉那個數據網格,但是大多數網格都有選項可以將Observable Collection中所有類型的公共屬性公開爲列,或者你明確地在XAML中設置一個列布局,以及列定義是用於列數據的對象的屬性。

例如與Infragistics數據網格

   <igDP:Field Name="OrderSize" Label="Order Size"> 
        <igDP:Field.Settings > 
         <igDP:FieldSettings CellWidth="75"> 
          <igDP:FieldSettings.EditorStyle> 
           <Style TargetType="{x:Type Editors:ValueEditor}" > 
            <Style.Setters> 
             <Setter Property="Format" Value="#,##0"/> 
            </Style.Setters> 
           </Style> 
          </igDP:FieldSettings.EditorStyle> 
         </igDP:FieldSettings> 
        </igDP:Field.Settings> 
       </igDP:Field> 

名稱是您設置要使用的對象的屬性的位置。

0

您的網格可以直接構建列,也可以指定您希望的列類型。如果你看這video,它會解釋它。這是針對VS2010的,但VS2008的基本原理是一樣的 - 雖然實現只是稍微有點不同,因爲它不是完整的。

至於如何綁定,將保存項目的ObservableCollection分配給網格的ItemsSource屬性。

3

我收集的是我應該把我的服務的結果放在ObservableCollection中,沒有汗水。但後來我想以某種方式將它綁定到我的數據網格。我怎樣才能做到這一點?

最簡單的方法是將DataGrid的ItemsSource屬性設置爲ObservableCollection。

網格如何知道要生成哪些列?

DataGrid反映該集合中的對象,併爲其找到的每個公共屬性創建一個列。有關更多信息,請參見here

如果您直接設置ItemsSource屬性,那麼它不是真正的wpf綁定。這裏有三個我在WPF中開始數據綁定時發現有用的鏈接。

Bea Stollnitz: What does 「{Binding}」 mean?
WPF Basic Data Binding FAQ
MSDN: Data Binding How-to Topics

+0

看起來這裏有一些很好的閱讀。現在沒有時間檢查它們,但是在我有了之後會回來。 – 2009-05-20 07:19:42

2

雖然可以使用這種一個ObservableCollection,這取決於如何使用它,你將不會從它recive任何中獲益, ObservableCollection的關鍵特性是它實現INotifyCollectionChanged。這個接口做的是提供一個通知機制來告訴UI屬性已經改變。因爲ObservableCollection已經實現了這個功能,所以如果你將DataGrid,ListBox,ItemsControl等的ItemSource屬性綁定到這個類型的集合上,它會在任何時候添加/刪除/替換/移動/重置時自動更新UI。因此,每次要使用新的IEnumerable結果集更新集合時,都必須先清除集合,然後添加新結果。

但是,在這種情況下,我建議通過ObservableCollection來推薦另一個選項。它是使用一種稱爲ObjectDataProvider的東西。使用這個我們可以完全避免背後的代碼,並且總體來說更乾淨。因此,我們有我們的地方服務,在這種情況下,我Window.xaml.cs

public class TranslationService 
{ 
    public IEnumerable<string> Translate(string s) 
    { 
     return s.ToCharArray().Select(c => c.ToString()); 
    } 
} 

像你描述的服務,它需要一個字符串從一個文本框,並返回一個IEnumerable。現在,在XAML中,我們可以使用此服務並調用它。

在窗口declerations,我們增加了在服務所在的命名空間:現在

xmlns:local="clr-namespace:WpfApplication4" 

,我們Window.Resources(或者用戶控件,或其他任何地方),我們可以參考我們的服務。一旦我們將我們的服務公開爲資源,我們就可以創建一個ObjectDataProvider來公開我們希望使用的Translate方法。

<Window.Resources> 
    <local:TranslationService x:Key="MyTranslationService" /> 
    <ObjectDataProvider x:Key="MyProvider" 
         ObjectInstance="{StaticResource MyTranslationService}" 
         MethodName="Translate"> 
     <ObjectDataProvider.MethodParameters> 
      "" 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</Window.Resources> 

ObjectDataProvider被鍵入我們的服務並使用String參數調用Translate方法。現在我們所要做的就是讓它響應我們的文本框。

我們可以通過使用一些綁定屬性來做到這一點。我們希望TextBox中的TextProperty綁定到ObjectDataProvider,因此我們將Source屬性設置爲指向它。我們要綁定到的PathData中的ObjectDataProvider部分是MethodParameter。現在,我們將其設置爲直接綁定到該屬性的源,並且僅以單向方式傳送,這意味着ObjectDataProvider的方法參數不會更新文本框的文本。最後,我們可以將UpdateSourceTrigger設置爲PropertyChanged,告訴綁定在對象數據提供程序中設置我們綁定的源,只要文本發生任何更改。

<StackPanel> 
     <TextBox TextChanged="OnTextChanged" 
      Text="{Binding Source={StaticResource MyProvider}, Path=MethodParameters[0], BindsDirectlyToSource=True, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" /> 
     <ListBox ItemsSource="{Binding Source={StaticResource MyProvider}}" /> 
    </StackPanel> 

剩下的就是在網格中設置ItemsSource,或者在這種情況下設置一個簡單的ListBox。

關於對DataGrid中的最後一部分: 如果您使用的是WPFToolkit的數據網格,它有一個自動生成功能,可以通過屬性進行設置,你可以在它身上找到here更多信息。

+0

謝謝,我想我可以應用這個例子沒有什麼變化。我不打算直接打電話給我的服務,因爲我不想每次擊鍵都觸發一個對我的服務(也就是我的翻譯數據庫)的調用,而是在它們之間有一個小的定時器緩衝區。但除此之外,它看起來很有希望。 – 2009-05-20 12:08:41