2009-05-19 9 views
0

Mein Szenario: Ein WPF-Formular hat eine Textbox und ein WPF toolkig datagrid. Wenn ein Text in das Textfeld eingegeben wird, gibt mein Dienst eine IEnumerable<TranslationItem> Elemente zurück. Ich möchte, dass mein Datagrid das Ergebnis dieses Dienstes anzeigt.Kann mich nicht um WPF Datenbindung wickeln

Ich habe versucht zu googeln, aber ich kann nicht Kopf oder Zahl davon bekommen. Ich lerne nur WPF und die meisten der verwendeten Begriffe entziehen sich mir.
Was ich zusammentrage, ist, dass ich das Ergebnis meines Dienstes in eine ObservableCollection setzen sollte, kein Problem. Aber dann möchte ich es irgendwie an mein Datagrid binden. Wie kann ich das machen? Woher weiß das Grid, welche Spalten generiert werden sollen?

Antwort

0

Sie legen die DataSource (oder sogar den DataContext) des Rasters für Ihre Observable Collection fest.

Ich bin mit diesem Datenraster nicht vertraut, aber die meisten Raster haben Optionen, um alle öffentlichen Eigenschaften des Typs in der Observable Collection als Spalten anzuzeigen, oder Sie legen explizit ein Spaltenlayout in XAML und eine der Eigenschaften von fest Die Spaltendefinition ist die Eigenschaft des Objekts, das für die Spaltendaten verwendet werden soll.

z.B. mit Infragistics Data Grid

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

Name ist, wo Sie die Eigenschaft für das Objekt festlegen, das verwendet werden soll.

0

Ihr Raster kann entweder die Spalten direkt erstellen oder Sie können die gewünschten Spaltentypen angeben. Wenn Sie diese video sehen, wird es erklären. Das ist für VS2010, aber die Grundlagen sind für VS2008 die gleichen - obwohl Implementierung ist nur ein bisschen anders, da es nicht ganz so integriert ist.

Ordnen Sie zur Bindung die ObservableCollection, die Ihre Elemente enthält, der ItemsSource-Eigenschaft des Rasters zu.

3

Was ich erhalte, ist, dass ich das Ergebnis meines Dienstes in eine ObservableCollection setzen sollte, kein Problem. Aber dann möchte ich es irgendwie an mein Datagrid binden. Wie kann ich das machen?

Der einfachste Weg ist die Itemssource-Eigenschaft des Datagrid auf die ObservableCollection einzustellen.

Woher weiß das Grid, welche Spalten generiert werden sollen?

Das DataGrid spiegelt die Objekte in dieser Auflistung wider und erstellt eine Spalte für jede gefundene öffentliche Eigenschaft. Weitere Informationen finden Sie unter here.

Wenn Sie die ItemsSource-Eigenschaft direkt festlegen, ist es nicht wirklich wpf-Bindung. Hier sind drei Links, die ich nützlich fand, als ich mit der Datenbindung in WPF begann.

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

+0

Sieht aus, als gäbe es hier eine gute Lektüre. Habe keine Zeit, sie jetzt zu überprüfen, werde aber zurückkehren, nachdem ich es getan habe. –

2

Während ein ObservableCollection dafür verwendet werden kann, je nachdem, wie es verwendet wird, werden Sie keine benifit von ihm erhalten speichert. Das Schlüsselmerkmal der ObservableCollection ist, dass sie INotifyCollectionChanged implementiert. Diese Schnittstelle stellt einen Benachrichtigungsmechanismus bereit, um der Benutzeroberfläche mitzuteilen, dass eine Eigenschaft geändert wurde.Da ObservableCollection das bereits implementiert, wenn Sie die ItemSource -Eigenschaft von DataGrid, ListBox, ItemsControl usw. an eine Sammlung dieses Typs binden, wird die Benutzeroberfläche automatisch aktualisiert, sobald ein Element hinzugefügt/entfernt/ersetzt/verschoben/zurückgesetzt wird. Daher müssen Sie jedes Mal, wenn Sie die Sammlung mit einer neuen IEnumerable-Ergebnismenge aktualisieren möchten, zuerst die Sammlung löschen und dann die neuen Ergebnisse hinzufügen.

Es gibt jedoch eine andere Option, die ich in diesem Fall über eine ObservableCollection empfehlen würde. Es ist etwas zu verwenden, das als ObjectDataProvider bezeichnet wird. Damit können wir den Code vollständig vermeiden und er ist insgesamt viel sauberer. Also haben wir unseren Service irgendwo haben, in diesem Fall in meinem Window.xaml.cs

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

Wie der Service, den Sie beschreiben, es dauert es eine Zeichenfolge aus einer Textbox, und gibt eine IEnumerable. Jetzt können wir diesen Dienst im XAML verwenden und Anrufe tätigen.

Im Fenster declerations, fügen wir den Namespace für wo der Dienst befindet:

xmlns:local="clr-namespace:WpfApplication4" 

nun in unserem Window.Resources (Oder Usercontrol oder anderswo) wir unseren Service verweisen können. Sobald wir unseren Dienst als Ressource bereitgestellt haben, können wir einen ObjectDataProvider erstellen, der die Translate-Methode verfügbar macht, die wir verwenden möchten.

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

Der ObjectDataProvider ist mit unserem Service verknüpft und ruft die Translate-Methode mit einem String-Parameter auf. Jetzt müssen wir nur noch auf unser Textfeld reagieren.

Wir können dies tun, indem Sie einige der Bindungseigenschaften verwenden. Wir möchten, dass unsere TextProperty in der TextBox an den ObjectDataProvider gebunden wird. Daher legen wir fest, dass die Source-Eigenschaft darauf verweist. Der Teil des ObjectDataProvider, an den wir im Pfad binden möchten, ist der MethodParameter. Jetzt legen wir fest, dass es direkt an die Quelle dieser Eigenschaft gebunden wird und nur in eine Richtung geht, was bedeutet, dass der Methodenparameter des ObjectDataProvider den Text der TextBox nicht aktualisiert. Schließlich können wir den UpdateSourceTrigger auf PropertyChanged setzen und die Bindung angeben, um die Quelle festzulegen, an die wir binden, im Objektdatenprovider, wenn sich der Text ändert.

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

dass links Alles, was ist die Itemssource im Grid oder eine einfache List-Box in diesem Fall einzustellen.

In Bezug auf den letzten Teil auf dem Datagrid: Wenn Sie das Datenraster des WPFToolkit verwenden, tut es Feature ein Auto erzeugen, die durch die Eigenschaften eingestellt werden können, und Sie können mehr Informationen über sie here finden.

+0

Danke, ich denke, ich kann dieses Beispiel mit kleinen Änderungen anwenden. Ich werde meinen Dienst nicht direkt anrufen, da ich nicht jeden Tastendruck wünschen würde, um einen Anruf zu meinem Dienst (und damit meine Übersetzungs-DB) auszulösen, sondern stattdessen einen kleinen Zeitpuffer dazwischen. Aber ansonsten sieht es vielversprechend aus. –