2009-02-26 7 views
15

(WPFToolkit Datagrid 내에서) WPF 콤보 박스를 사용하려고하는데 모든 조각을 올바르게 정렬하는 데 문제가 있습니다. 내가 엔티티에 Linq를 사용하고, 그리고 내가 LINQ 쿼리의 결과를 전체 데이터 컨텍스트를 설정 해요 :WPF ComboBox가 소스를 업데이트하지 않습니다.


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

나는 또한 콤보 상자의 ItemsSource를 제공 ​​내 코드 숨김의 페이지 속성이 있습니다 :


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

콤보 상자의 XAML은 다음과 같습니다

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

그리고 모든 예는, 적절한 값이 바로 포인트 어까지 콤보 상자에 표시됩니다 올바르게 작동하는 것 같다 포커스가 ComboBox를 벗어납니다. 이 시점에서 표시된 값은 새로 선택된 값이 아닌 원래 값으로 돌아갑니다. SelectedValue 대신 SelectedItem을 사용하여 시도했지만 ComboBox에 표시되지 않는 선택한 값으로 끝납니다. 나는 다소 신비스럽게 생각합니다.이 비트가 작동해야하는 것처럼 보입니다.

편집 됨 3/2/09 : 나는이 문제에 여전히 의문을 품고 있습니다. 내 DataGrid에서 간단한 데이터 열 (예 : "DataGridTextColumn")은 기본 데이터 소스를 예상대로 업데이트합니다. 그러나 내 템플릿이있는 열 ("DataGridTemplateColumn") 또는 ComboBox 열 ("DataGridComboBoxColumn")에 대한 업데이트는 작동하지 않습니다. 기본 데이터 소스는 결코 업데이트되지 않습니다. 분명히 다른 사람들은 WPF.Toolkit 데이터 격자를 사용하려고 시도했으며이 시나리오를 작동 시키려고했지만 - 거기서 모든 샘플 코드를 살펴 봤는데 기본적으로 말한대로 (내 제약 조건 내에서) 솔루션), 그래서 왜 작동하지 않습니다 내 머리를 긁적입니다.

의견이 있으십니까?

답변

20

나는 (내가 좌절감을 보냈다) 비슷한 문제가 있었는데, PropertyChanged 바인딩을 SelectedValue 바인딩에 붙인 것은 UpdateSourceTrigger이라는 것을 발견했다. 왜 그런지 모르겠지만 나에게이 변경 작업을하기 전까지는 데이터 소스가 업데이트되지 않았습니다.

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

나는 정확히 같은 문제가있었습니다. 이것을 몇 시간 동안 어지럽 혔다. TwoWay에 대한 바인딩을 변경하고 다른 많은 호스트를 변경하려고 시도했습니다. [MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx) Text와 같은 경우 기본값이 LostFocus로 설정됨을 나타냅니다. –

+0

사실, 텍스트 상자를 사용할 때 실제로 LostFocus를 기본값으로 설정하지 않습니다. PropertyChanged로 설정하면이 문제가 해결됩니다. – tcables

+0

우수 !! SamIted는 SelectedItem 바인딩에 대해서도 작동합니다. – Adarsha

5

이 작업을 수행 할 수있었습니다. 하지만 나는 상황을 조금 다르게 설정했습니다.

  1. 뷰와 계약을 맺기 위해 ViewModel을 만들었습니다.
  2. 은 내가 데이터 소스 내가 만들어 있었는지 몰랐 때문에 재산권

대신 ComboBox.SelectedValue의 ComboBox.SelectedItem 속성에 바인딩 내 기본적인 문제를 시뮬레이션 할 자신 : 제대로 콤보 상자 바인딩을 갖는 WPF DataGrid 내에서. 우리가 시작하기 전에

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

, 내 제대로 구성 RootViewModel의 인스턴스 내 윈도우의 DataContext를 설정 : 여기

내보기 모델의 구성이다. 나는 후드 아래에 있기 때문에 내 개체의 Equals 메서드를 오버라이드 (override)했는지 확인해야 제대로 결합 할 수있는 selectedItem을 위해서는

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

는, WPF는 selectedItem가인지 누가 결정하기 위해이 방법을 사용하고 있습니다. 이것은 기본적으로 SelectedItem 대신 SelectedValue에 바인딩하려고했던 근본적인 문제라고 생각합니다.

0

당신은 당신의 XAML에서

IsSynchronizedWithCurrentItem = "True" 

를 추가해야합니다.

그것은 간단합니다 ...

+2

'False'로 설정하면 비슷한 문제가 해결되었습니다. –

관련 문제