2010-07-26 1 views
11

binden Ich versuche, den Schlüssel eines Wörterbuchs an eine Zeile des Rasters in einer Listbox zu binden, und den Wert des Dictionary an eine andere Zeile des Rasters zu binden. Der Typ des Schlüssels ist Book, eine Klasse, die geschrieben wurde, und der Typ des Werts ist int. Ich möchte die Elemente der Klasse und den Integer-Wert im Raster schreiben. Können Sie mir dabei helfen? Ich bin ziemlich verwirrt, wenn ich die itemsSource und den zu bindenden Datentyp festlege. danke für die hilfeDen Schlüssel und den Wert eines Dictionary in einer Listbox mit wpf

Edit: ich habe vergessen zu sagen, dass ich C# - wpf. =)


schickte ich das Wörterbuch als Itemssource und i angegeben, das Wörterbuch als Typ in Object Tag und versuchte, den Wert (int) durch diesen Code zu senden:

< TextBlock Text="{Binding Value, Mode=OneWay}" Grid.Row="1" Width="65" > 

und die SelectedItem wurde als [myNameSpace.Book, 4] gezeigt, statt nur von 4.


BookListBox.ItemsSource = LibManager.Books; 

das ist, was ich in Win schrieb dow.xaml.cs und Books ist eine BookList, wobei BookList eine Art Wörterbuch ist < Buch, int>.

und die XAML-Datei:

< ListBox Height="571" HorizontalAlignment="Left" Margin="444,88,0,0" 
      Name="BookListBox" VerticalAlignment="Top" Width="383" > 
     < ListBox.Resources> 
      <ObjectDataProvider x:Key="BookData" 
           ObjectType="{x:Type local:BookList}"/> 
     </ListBox.Resources> 
     < ListBox.ItemTemplate> 
      < DataTemplate> 
       < Border BorderThickness="2" BorderBrush="Black" Margin="5" 
         CornerRadius="5" Width="350" > 
        < Grid DataContext="{StaticResource BookData}" > 
         < Grid.ColumnDefinitions> 
          < ColumnDefinition/>       
         </Grid.ColumnDefinitions> 
         < Grid.RowDefinitions> 
          < RowDefinition/> 
          < RowDefinition/> 
         < /Grid.RowDefinitions> 
         < Label Content="count: " /> 
         < TextBlock Text="{Binding Value, Mode=OneWay}" 
            Grid.Row="1" Width="65"/> 
        < /Grid> 
       < /Border> 
      < /DataTemplate> 
     < /ListBox.ItemTemplate> 
    < /ListBox> 

gibt es ein weiteres Problem mit meinem code-- Ich kann nicht alle Gegenstände in listbox sehen. Ich meine, ich könnte die Werte von ListBox.SelectedItem bekommen, konnte aber nicht in der Listbox sehen. daher kann ich nicht sicher sein, ob ich den Integer-Wert an den gewünschten Ort weitergeben könnte.

Also ich denke ich brauche auch Hilfe für dieses Problem zuerst ... Ich schreibe ein Etikett, dass ich von Hand schreiben, und ein anderes Etikett, das durch Datenbindung in der gleichen Zeile gefüllt werden sollte, aber ich kann nur die erste sehen Label, aber ich kann den Wert im Code dahinter erreichen.

+0

Welche Sprache/Framework verwenden Sie? Es klingt wie .NET für mich, aber Sie sollten klären. – LukeH

+0

Cemre, können Sie Ihren Code bitte mit uns teilen? –

+0

keine Idee/Anregung/Hilfe? – cemregoksu

Antwort

29

Im Folgenden Code liefert der folgende:

1 
Book 1 
------- 
2 
Book 2 
------- 
3 
Book 3 

SelectedBookIndex wird dem Index des ausgewählten Buches festgelegt werden, auf das zweite Buch ausgewählt werden beginnen.

XAML:

<Window x:Class="TestDemo.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 

    <StackPanel> 
     <ListBox 
      ItemsSource="{Binding Path=Books}" 
      SelectedValuePath="Value" 
      SelectedValue="{Binding Path=SelectedBookIndex}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Border BorderBrush="Black" BorderThickness="2"> 
         <StackPanel> 
          <TextBlock Text="{Binding Path=Value}" /> 
          <TextBlock Text="{Binding Path=Key.Name}" /> 
         </StackPanel> 
        </Border> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </StackPanel> 
</Window> 

-Code hinter:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Windows; 

namespace TestDemo 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      Books = new Dictionary<Book, int>(); 
      Books.Add(new Book() { Name = "Book 1"}, 1); 
      Books.Add(new Book() { Name = "Book 2" }, 2); 
      Books.Add(new Book() { Name = "Book 3" }, 3); 

      SelectedBookIndex = 2; 

      DataContext = this; 
     } 

     public Dictionary<Book, int> Books { get; set; } 

     private int _selectedBookIndex; 
     public int SelectedBookIndex 
     { 
      get { return _selectedBookIndex; } 
      set 
      { 
       _selectedBookIndex = value; 
       Debug.WriteLine("Selected Book Index=" + _selectedBookIndex); 
      } 
     } 
    } 

    public class Book 
    { 
     public string Name { get; set; } 
    } 
} 
+0

diese Lösung hat perfekt funktioniert. vielen Dank =) – cemregoksu

+0

kann ich nicht .. Warum ?? –

+0

Diese Lösung funktioniert nicht mehr, da Sie das Wörterbuch in ObservableDictionary (das INotifyCollectionChanged und INotifyPropertyChanged implementieren muss) ändern müssen. –

0

Entfernen Sie DataContext="{StaticResource BookData}" aus dem Rasterelement.

Der ObjectDataProvider erstellt eine neue, leere BookList, und Ihr TextBlock erbt diesen DataContext. Wenn Sie dieses Attribut entfernen, erhält der TextBlock seinen DataContext vom aktuellen Element im ItemsControl, das die KeyValuePair für diese Zeile darstellt. Sie können das ObjectDataProvider-Element wahrscheinlich vollständig entfernen, da Sie die Daten im Code erstellen.

+0

aber sollte ich nicht den Objekttyp implementieren? – cemregoksu

+0

@cemregoksu: Ich bin mir nicht sicher, was Sie meinen, indem Sie den Objekttyp implementieren. Sie müssen WPF keine Typinformationen bereitstellen. es liest es aus dem Laufzeittyp des Objekts. ObjectDataProvider wird verwendet, wenn Sie ein Objekt in XAML mithilfe eines Methodenaufrufs oder über die Bereitstellung von Konstruktorparametern erstellen möchten. Da Sie bereits ein Objekt haben, können Sie es einfach ItemsSource zuweisen. – Quartermeister