2009-02-26 31 views
15

Tôi đang cố gắng để có được một combobox WPF làm việc (bên trong WPFToolkit Datagrid), và tôi gặp khó khăn khi nhận được tất cả các mảnh liên kết chính xác. Tôi đang sử dụng LINQ to Entities, và tôi đang thiết lập các DataContext tổng thể để kết quả của một truy vấn LINQ:WPF ComboBox không cập nhật nguồn


private void LoadDonationGrid() 
{ 
    donationGrid.ItemsSource = from donations in entities.Donation 
        .Include("Family") 
        .Include("PledgeYear") 
        .Include("DonationPurpose") 
       from donationPurposes in entities.DonationPurpose 
       select new { donations, donationPurposes }; 
} 

Tôi cũng có một tài sản trang trong code-behind của tôi cung cấp các ItemsSource cho combobox:


private IEnumerable donationPurposeList; 
public IEnumerable DonationPurposeList 
{ 
    get 
    { 
     if (donationPurposeList == null) 
     { 
      donationPurposeList = from dp in entities.DonationPurpose 
            select dp; 
     } 
     return donationPurposeList.ToList(); 
    } 
} 

các XAML cho combobox trông như thế này:

<tk:DataGridTemplateColumn Header="Purpose"> 
    <tk:DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=donations.DonationPurpose.Description, Mode=TwoWay}" /> 
     </DataTemplate> 
    </tk:DataGridTemplateColumn.CellTemplate> 
    <tk:DataGridTemplateColumn.CellEditingTemplate> 
     <DataTemplate> 
      <ComboBox Name="cboDonationPurpose" 
       SelectedValue="{Binding Path=donations.DonationPurposeID, Mode=TwoWay}" 
       ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor},Path=DonationPurposeList}"         
       DisplayMemberPath="Description" 
       SelectedValuePath="DonationPurposeID" 
         /> 
     </DataTemplate> 
    </tk:DataGridTemplateColumn.CellEditingTemplate> 
</tk:DataGridTemplateColumn> 

Và tất cả mọi thứ dường như làm việc một cách chính xác, ví dụ, các giá trị thích hợp được hiển thị trong ComboBox, phải lên đến wh điểm ere tập trung lá ComboBox. Tại thời điểm đó, giá trị được hiển thị trở về giá trị ban đầu, không phải giá trị mới được chọn. Tôi đã thử bằng cách sử dụng SelectedItem thay vì SelectedValue, nhưng kết thúc với giá trị được chọn không hiển thị trong ComboBox. Tôi khá là hoang mang: có vẻ như việc này nên có tác dụng.

Đã chỉnh sửa 3/2/09: Tôi vẫn đang bối rối về điều này. Tôi nên lưu ý rằng trong dữ liệu của tôi, bất kỳ cột dữ liệu đơn giản nào (ví dụ: "DataGridTextColumn") cập nhật nguồn dữ liệu cơ bản giống như bạn mong đợi. Nhưng bất kỳ cập nhật cho bất kỳ cột templated của tôi ("DataGridTemplateColumn") hoặc ComboBox cột ("DataGridComboBoxColumn") không hoạt động: nguồn dữ liệu cơ bản không bao giờ được cập nhật. Chắc chắn những người khác đã cố gắng sử dụng dữ liệu WPF.Toolkit và nhận kịch bản này để làm việc - nhưng tôi đã xem xét tất cả các mã mẫu ở đó, và tôi đang làm cơ bản những gì nó nói để làm (trong các ràng buộc của tôi giải pháp), vì vậy tôi gãi đầu vì sao điều này không hiệu quả.

Mọi suy nghĩ?

Trả lời

20

Tôi đã gặp phải sự cố tương tự (mà tôi đã trải qua nhiều ngày thất vọng) và tôi thấy rằng việc thay đổi UpdateSourceTrigger trên SelectedValue ràng buộc để PropertyChanged sửa lỗi. Tôi không biết tại sao, nhưng đối với tôi, nguồn dữ liệu không được cập nhật cho đến khi tôi thực hiện thay đổi này.

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UpdateTypesManager:MainWindow}}, Path=CardinalityTypes}" 
    DisplayMemberPath="CardinalityType" 
    SelectedValue="{Binding CardinalityTypeId, UpdateSourceTrigger=PropertyChanged}" 
    SelectedValuePath="Id" /> 
+0

Tôi đã có chính xác cùng một vấn đề. Đã rối tung với điều này trong nhiều giờ. Tôi đã thay đổi ràng buộc thành TwoWay, cố gắng thay đổi toàn bộ các thứ khác. [MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx) dường như cho biết mặc định được đặt thành LostFocus trong các trường hợp như Văn bản. –

+0

Trên thực tế, nó không phải là mặc định để LostFocus cho tôi khi tôi sử dụng một hộp văn bản. Đặt nó thành PropertyChanged sẽ sửa lỗi này. – tcables

+0

Tuyệt vời !! Samething hoạt động ngay cả đối với SelectedItem ràng buộc – Adarsha

5

Tôi có thể làm việc này. Nhưng tôi đặt mọi thứ lên một chút khác biệt.

  1. Tôi đã tạo ViewModel hoạt động như một hợp đồng với Chế độ xem.
  2. tôi ràng buộc với ComboBox.SelectedItem tài sản thay vì ComboBox.SelectedValue tài sản

Vì tôi không biết chuyện gì nguồn dữ liệu của bạn đã được tôi đã quyết của riêng tôi để mô phỏng các vấn đề cơ bản: có một ràng buộc combobox một cách chính xác trong một DataGrid WPF.

Dưới đây là các thành phần của Xem các mẫu của tôi:

public class RootViewModel 
{ 
    public List<State> USStates { get; set; } 
    public List<Customer> Customers { get; set; } 

    public ViewModel() 
    { 
     Customers = new List<Customer>(); 
     Customers.Add(new Customer() { FirstName = "John", LastName = "Smith", State = new State() { ShortName = "IL" } }); 
     Customers.Add(new Customer() { FirstName = "John", LastName = "Doe", State = new State() { ShortName = "OH" } }); 
     Customers.Add(new Customer() { FirstName = "Sally", LastName = "Smith", State = new State() { ShortName = "IN" } }); 

     USStates = new List<State>(); 
     USStates.Add(new State() { ShortName = "OH" }); 
     USStates.Add(new State() { ShortName = "IL" }); 
     USStates.Add(new State() { ShortName = "IN" }); 
    } 
} 

public class Customer 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public State State { get; set; } 
} 

public class State 
{ 
    public string ShortName { get; set; } 

    public State() 
    { 
     ShortName = string.Empty; 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj is State) 
     { 
      State otherState = obj as State; 
      return ShortName.Equals(otherState.ShortName); 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

Trước khi chúng tôi bắt đầu, tôi đặt DataContext của Window của tôi là một thể hiện của RootViewModel xây dựng đúng cách của tôi.

<tk:DataGrid ItemsSource="{Binding Customers}" AutoGenerateColumns="False"> 
      <tk:DataGrid.Columns> 
       <tk:DataGridTemplateColumn Header="State"> 
        <tk:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding Path=State.ShortName, Mode=TwoWay}" /> 
         </DataTemplate> 
        </tk:DataGridTemplateColumn.CellTemplate> 
        <tk:DataGridTemplateColumn.CellEditingTemplate> 
         <DataTemplate> 
          <ComboBox 
           x:Name="cboDonationPurpose" 
           SelectedItem="{Binding Path=State, Mode=TwoWay}" 
           ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window},Mode=FindAncestor}, Path=DataContext.USStates}" 
           DisplayMemberPath="ShortName" 
           SelectedValuePath="ShortName" /> 
         </DataTemplate> 
        </tk:DataGridTemplateColumn.CellEditingTemplate> 
       </tk:DataGridTemplateColumn> 
      </tk:DataGrid.Columns> 
     </tk:DataGrid> 

Để SelectedItem để ràng buộc đúng tôi cần phải đảm bảo rằng tôi đã overriden phương pháp Equals trên thực thể của tôi từ dưới mui xe, WPF đang sử dụng phương pháp này để xác định ai là SelectedItem hay không. Tôi nghĩ rằng điều này về cơ bản là vấn đề của bạn ngay từ đầu đã khiến bạn cố gắng liên kết với SelectedValue thay vì SelectedItem.

0

Bạn cần phải thêm

IsSynchronizedWithCurrentItem = "True" 

trong XAML của bạn.

Nó đơn giản như vậy ...

+2

Đặt nó thành 'False' đã giải quyết được vấn đề tương tự của tôi. –

Các vấn đề liên quan