2012-02-22 26 views
50

Tôi đang cố ràng buộc một danh sách các giá trị chuỗi vào một hộp danh sách để các giá trị của chúng được liệt kê theo từng dòng. Ngay bây giờ tôi sử dụng này:Làm cách nào để dữ liệu có thể gắn một danh sách các chuỗi vào một ListBox trong WPF/WP7?

<ListBox Margin="20" ItemsSource="{Binding Path=PersonNames}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Path=Id}"></TextBlock> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Nhưng tôi không biết những gì tôi đang phải đưa vào TextBlock, thay vì Id, vì họ là tất cả các giá trị chuỗi, không phải lớp tùy chỉnh.

Ngoài ra, nó cũng không phải tìm ra PersonNames khi tôi có nó trong MainPage, như MainPage.PersonNames.

tôi đặt bối cảnh dữ liệu:

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

tôi đang làm sai?

Trả lời

111

Nếu chỉ cần đặt rằng ItemsSource của bạn được ràng buộc như thế này:

YourListBox.ItemsSource = new List<String> { "One", "Two", "Three" }; 

XAML của bạn sẽ giống như thế:

<ListBox Margin="20" Name="YourListBox"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Cập nhật:

Đây là giải pháp khi sử dụng DataContext. mã sau là viewmodel bạn sẽ được đi đến DataContext của trang và các thiết lập của DataContext:

public class MyViewModel 
{ 
    public List<String> Items 
    { 
     get { return new List<String> { "One", "Two", "Three" }; } 
    } 
} 

//This can be done in the Loaded event of the page: 
DataContext = new MyViewModel(); 

XAML của bạn bây giờ trông như thế này:

<ListBox Margin="20" ItemsSource="{Binding Items}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Ưu điểm của phương pháp này là bạn có thể đặt nhiều thuộc tính hoặc các đối tượng phức tạp hơn trong lớp MyViewModel và giải nén chúng trong XAML. Ví dụ để vượt qua một danh sách các đối tượng Person:

public class ViewModel 
{ 
    public List<Person> Items 
    { 
     get 
     { 
      return new List<Person> 
      { 
       new Person { Name = "P1", Age = 1 }, 
       new Person { Name = "P2", Age = 2 } 
      }; 
     } 
    } 
} 

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

Và XAML:

<ListBox Margin="20" ItemsSource="{Binding Items}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Path=Name}" /> 
       <TextBlock Text="{Binding Path=Age}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Hope this helps!:)

+1

Cảm ơn, tôi bị nhầm lẫn bởi YourListBox. Đó có phải là tên của kiểm soát không? Bạn có phải dòng đầu tiên trong mã cho xaml để làm việc? –

+1

Đó là một lỗi đánh máy, nó thực sự là Tên của Kiểm soát. Bạn cũng có thể liên kết các mục thông qua một DataContext trên trang của bạn hoặc thông qua Tài nguyên. Các ràng buộc tôi đã cho là cho mục đích demo. :) – Abbas

+0

Cảm ơn, bạn có thể cho tôi một ví dụ cho DataContext không? Tôi có một thời gian khó hiểu nó. –

8

Nếu nguồn mục là đếm được như chuỗi-mục, sử dụng như sau:

<TextBlock Text="{Binding}"></TextBlock> 

Bạn có thể sử dụng cú pháp này trên bất kỳ đối tượng. Nói chung, ToString() -method sau đó sẽ được gọi để nhận giá trị. Đây là trong nhiều trường hợp rất tiện dụng. Nhưng hãy cẩn thận rằng không có thông báo thay đổi nào sẽ xảy ra.

+0

Cảm ơn, tôi sẽ cố gắng này nhưng tôi vẫn còn có một vấn đề với phần ràng buộc, nơi nó than phiền không tìm thấy PersonNames trong xaml. –

+0

+1 để chỉnh sửa và cung cấp thông tin -toString – mindandmedia

+0

@Janan Venge: Vấn đề ràng buộc là một vấn đề khác và không được giải thích nhanh chóng trong một nhận xét. Tôi giả định rằng DataContext của UserControl hoặc Window của bạn không được đặt thành cá thể PersonNames-exposing. Nếu nó được khai báo trong Window hoặc UserControl, bạn có thể thêm một giải pháp nhanh sau đây vào liên kết {Binding PersonNames, RelativeSource = {RelativeSource Mode = FindAncestor, AncestorType = Window}}, nơi bạn phải thay thế "Window" qua "UserControl "nếu ListBox của bạn nằm trong UserControl. Kiểm tra một số bài viết về DataContext và MVVM, điều này sẽ giúp bạn hiểu DataContext – HCL

10

Bạn nên cho chúng ta thấy Mã cho PersonNames, và tôi không chắc chắn, tôi hiểu câu hỏi của bạn, nhưng có lẽ bạn muốn để ràng buộc nó như thế này:

<TextBlock Text="{Binding Path=.}"/> 

hoặc

<TextBlock Text="{Binding"} /> 

này sẽ liên kết với phần tử hiện tại trong danh sách. (Giả sử PersonNames là một danh sách các chuỗi). Nếu không, bạn sẽ thấy tên lớp trong danh sách

+3

Với 'Path = .' là bắt buộc đối với các liên kết hai chiều – Dani

1

Bạn có thể làm điều này mà không cần phải xác định rõ ràng điều khiển TextBlock như một phần của ListBox của bạn (trừ khi bạn muốn định dạng tốt hơn). Bí quyết để nhận được các ràng buộc để kích hoạt được sử dụng một ObservableCollection<string> thay vì List<string>

Window1.XAML

<ListView Width="250" Height="50" ItemsSource="{Binding MyListViewBinding}"/> 

Window1.xaml.cs

public Window1() 
{ 
    InitializeComponent(); 
    DataContext = this; 

    // Need to initialize this, otherwise you get a null exception 
    MyListViewBinding = new ObservableCollection<string>(); 
} 

public ObservableCollection<string> MyListViewBinding { get; set; } 

// Add an item to the list   
private void Button_Click_Add(object sender, RoutedEventArgs e) 
{ 
    // Custom control for entering a single string 
    SingleEntryDialog _Dlg = new SingleEntryDialog(); 

    // OutputBox is a string property of the custom control 
    if ((bool)_Dlg.ShowDialog()) 
     MyListViewBinding.Add(_Dlg.OutputBox.Trim()); 
} 
Các vấn đề liên quan