2009-02-26 22 views
15

Estoy tratando de obtener un combobox WPF funcionando (dentro de WPFToolkit Datagrid), y tengo problemas para alinear todas las piezas correctamente. Estoy usando LINQ a Entidades, y estoy estableciendo el DataContext en general a los resultados de una consulta LINQ:WPF ComboBox no actualiza fuente


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

también tengo una propiedad en mi página de código subyacente que proporciona la ItemsSource para el cuadro combinado:


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

el XAML para el cuadro combinado tiene el siguiente aspecto:

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

Y todo parece funcionar correctamente, es decir, los valores correspondientes se muestran en el cuadro combinado, hasta los Puntos WH El enfoque deja el ComboBox. En ese punto, el valor mostrado vuelve al valor original, no al valor recién seleccionado. He intentado usar SelectedItem en lugar de SelectedValue, pero eso termina con el valor seleccionado que no se muestra en el ComboBox. Estoy un poco desconcertado: parece que este bit debería estar funcionando.

Editado el 2/03/09: Todavía estoy desconcertado por esto. Debo señalar que en mi cuadrícula de datos, cualquier columna simple de datos (por ejemplo, "DataGridTextColumn") actualiza la fuente de datos subyacente tal como cabría esperar. Pero cualquier actualización de cualquiera de mis columnas con plantilla ("DataGridTemplateColumn") o columnas ComboBox ("DataGridComboBoxColumn") no funciona: la fuente de datos subyacente nunca se actualiza. Seguramente otras personas han intentado usar la cuadrícula de datos WPF.Toolkit y han conseguido que funcione este escenario, pero he analizado todo el código de muestra, y básicamente estoy haciendo lo que dice que hacer (dentro de las limitaciones de mi solución), así que me estoy rascando la cabeza por qué esto no está funcionando.

¿Alguna idea?

Respuesta

20

que tenía un problema similar (en la que pasé días de frustración), y me encontré con que el cambio de la UpdateSourceTrigger en el SelectedValue unión a PropertyChanged lo arreglen. No sé por qué, pero para mí, el origen de datos no se actualizaba hasta que realicé este cambio.

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

Tuve exactamente el mismo problema. Estuve jugando con esto por horas. Cambié el enlace a TwoWay, intenté cambiar una gran cantidad de otras cosas. [MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx) parece indica que el valor predeterminado está configurado en LostFocus en casos como Texto. –

+0

En realidad, LostFocus no está predeterminado para mí cuando uso un cuadro de texto. Sin embargo, establecerlo en PropertyChanged lo soluciona. – tcables

+0

Excelente !! Lo mismo funciona incluso para el enlace SelectedItem – Adarsha

5

Pude hacerlo funcionar. Pero configuré las cosas un poco diferente.

  1. Creé un ViewModel para actuar como un contrato con la Vista.
  2. me vinculado a la propiedad ComboBox.selectedItem en lugar de ComboBox.SelectedValue Propiedad

Como yo no sabía lo que su fuente de datos se me hizo mi propio para simular el problema básico: tener un aprieto comboBox correctamente dentro de un WGD DataGrid.

Aquí está la composición de mi punto de vista del modelo:

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

Antes de empezar, me puse el DataContext de mi ventana a ser una instancia de mi RootViewModel correctamente construido.

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

Para que el SelectedItem para enlazar adecuadamente necesito para asegurar que he anulado el método Equals en mi entidad ya que bajo el capó, WPF está utilizando este método para determinar quién es el SelectedItem o no. Creo que este fue fundamentalmente su problema desde el principio, que hizo que intente vincularse a SelectedValue en lugar de SelectedItem.

0

es necesario agregar

IsSynchronizedWithCurrentItem = "True" 

en su Xaml.

Es tan simple como eso ...

+2

Configurarlo en 'False' ha resuelto un problema similar al mío. –

Cuestiones relacionadas