Pregunta

Situación:

He creado un DataGrid en XAML y ItemsSource está vinculado a una ObservableCollection de una determinada clase que contiene propiedades. Luego, en C #, creo un DataGridTextColumn y un DataGridComboBoxColumn y los uní a las propiedades de los objetos dentro de ObservableCollection. Puedo vincular DataGridComboBoxColumn a una Colección simple, pero lo que quiero hacer es vincularlo a una colección de colecciones de cadenas para que para cada fila el ComboBox dentro de DataGrid tenga una colección diferente de cadenas. No he podido hacerlo ...

Pregunta:

¿Cómo puedo vincular DataGridCombBoxColumn para que pueda tener una colección diferente de cadenas para cada fila de este tipo de columna?

Muestra de código:

XAML:

<Window>
  <!-- ... -->
  WPFToolkit:DataGrid
           x:Name="DG_Operations"
           Margin="10,5,10,5" 
           Height="100" 
           HorizontalAlignment="Stretch" 
           FontWeight="Normal" 
           ItemsSource="{Binding Path=OperationsStats}"
           AlternatingRowBackground="{DynamicResource SpecialColor}" 
           HorizontalScrollBarVisibility="Auto" 
           VerticalScrollBarVisibility="Visible" 
           SelectionMode="Extended"
           CanUserAddRows="False" 
           CanUserDeleteRows="False"
           CanUserResizeRows="True" 
           CanUserSortColumns="True"
           AutoGenerateColumns="False" 
           IsReadOnly="False" 
           IsEnabled="True"
           BorderThickness="1,1,1,1" 
           VerticalAlignment="Stretch"/>
  <!-- ... -->
</Window>

C#:

public class DataModelStatsOperations
{
   public ObservableCollection<IStatsOperation> OperationsStats { get; set; }
}

public interface IStatsOperation
{
   string Operation { get; set; }
   Collection<string> Data{ get; set; }
}

public class StatsOperation : IStatsOperation
{
    public StatsOperation(string operation, Collection<string> data)
    {
        Operation = operation;
        Data = data;
    }
    public string Operation { get; set; }
    public Collection<string> Data{ get; set; }
}

private ObservableCollection<IStatsOperation> dataOperations_ =
        new ObservableCollection<IStatsOperation>();

//...
 Binding items = new Binding();
 PropertyPath path = new PropertyPath("Operation");
 items.Path = path;
 DG_Operations.Columns.Add(new DataGridTextColumn()
 {
     Header = "Operations",
     Width = 133,
     Binding = items
  });
  DG_Operations.Columns.Add(new DataGridComboBoxColumn()
  {
     Header = "Data",
     Width = 190,
     ItemsSource = /*???*/,
     SelectedValueBinding = new Binding("Data"),
     TextBinding = new Binding("Data")
  });
dataOperations_.Add(new StatsOperation(CB_Operation.SelectedItem.ToString(),
                                                           dataCollection));
DG_Operations.DataContext = new DataModelStatsOperations
{
    OperationsStats = dataOperations_
};
//...

¡Cualquier ayuda sería muy apreciada!

Notas:

Bien, entonces después de leer las dos primeras respuestas noté algo. ¡Mi encuadernación realmente no está bien! Ahora, lo que quiero hacer es algo similar a lo que AndyG propuso:

DG_Operations.Columns.Add(new DataGridComboBoxColumn()
{
    Header = "Data",
    Width = 190,
    ItemsSource = new Binding("Data"), //notice this here does not work (have a look at the following error)
    SelectedValueBinding = new Binding("Operation"),
    TextBinding = new Binding("Operation")
});

Error: " No se puede convertir implícitamente el tipo 'System.Windows.Data.Binding' a 'System.Collections.IEnumerable'. "

¿Cómo se puede vincular ItemsSource a los datos?

¿Fue útil?

Solución

En primer lugar, esto debería ser fácil ... en segundo lugar, ¿por qué está construyendo (y vinculando) columnas en C #? Eek.

XAML (estoy usando una grilla regular porque soy vago):

<ListView Name="MyListView">
    <ListView.View>
        <GridView>

            <GridView.Columns>

                <GridViewColumn DisplayMemberBinding="{Binding Operation}" />

                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Choices}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

            </GridView.Columns>

        </GridView>
    </ListView.View>
</ListView>

C # :

void Window1_Loaded(object sender, RoutedEventArgs e)
{
    var dahList = new List<StatsOperation>();

    dahList.Add(new StatsOperation
    {
        Operation = "Op A",
        Choices = new string[] { "One", "Two", "Three" },
    });

    dahList.Add(new StatsOperation
    {
        Operation = "Op B",
        Choices = new string[] { "4", "5", "6" },
    });

    this.MyListView.ItemsSource = dahList;
}

Los resultados:

Cuadrícula WPF con opciones de cuadro combinado dinámico http: // www.singingeels.com/Articles/Articles/UserImage.aspx?ImageID=b1e3f880-c278-4d2b-bcc2-8ad390591200

Otros consejos

Creo que el error está en cómo has hecho tu enlace. Cuando define una columna, el enlace está relacionado con el objeto que está representado por una fila en particular. Entonces, según tengo entendido, tiene una StatsOperation para cada fila, por lo que la columna TextBox está vinculada a la operación, que es la forma en que la tiene, y la columna ComboBox ItemsSource debe estar vinculada a una Colección. En este momento parece que está vinculado a un Collection<Collection<string>>.

No he definido columnas en código subyacente antes, así que aquí hay un ejemplo en XAML. He encontrado que ComboBoxColumn puede ser complicado a veces, así que he mostrado cómo puede tener un cuadro combinado en la columna utilizando una TemplateColumn o un ComboBoxColumn. He copiado pegado de mi propio código, así que simplemente reemplace 'dg' con 'WPFToolkit' en su caso:

<dg:DataGrid
      ...
      ...>
      <dg:DataGrid.Columns>
            <dg:DataGridTextColumn Binding="{Binding Operation}" CanUserReorder="True" CanUserResize="True" Header="Operation" />
            <dg:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" Header="Template Column">
                <dg:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Data}" SelectedItem="{Binding Operation}" />
                    </DataTemplate>
                </dg:DataGridTemplateColumn.CellTemplate>
            </dg:DataGridTemplateColumn>
            <dg:DataGridComboBoxColumn
                Header="ComboBox Column"                                                                                    
                 SelectedValueBinding="{Binding Operation}"                     
                 SelectedItemBinding="{Binding Operation}">
                <dg:DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                    </Style>
                </dg:DataGridComboBoxColumn.ElementStyle>
                <dg:DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                        <Setter Property="IsDropDownOpen" Value="True" />
                    </Style>
                </dg:DataGridComboBoxColumn.EditingElementStyle>
            </dg:DataGridComboBoxColumn>
      </dg:DataGrid.Columns>

</dg:DataGrid>

Supongo que Operation es el elemento seleccionado, Data es el elemento para seleccionar y que DataGrid está vinculado a una colección de StatsOperation. ¡Buena suerte!

Para corregir su Error de enlace de ItemsSource use el formulario:

BindingOperations.SetBinding(new DataGridComboBoxColumn(), DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data"));

Obviamente, no puede hacer esto en el inicializador, por lo que tendrá que mover sus declaraciones un poco, pero eso debería solucionar ese error en su actualización.

EDITAR Lo siento, soy un poco lento a medianoche :). Aquí hay una respuesta actualizada. Parece un gran artículo de Vincent Sibal WPF DataGrid - DataGridComboBoxColumn v1 Intro responde a su pregunta. ¿Lo hace?

Parcial: creo que hay una confusión en lo que estás diciendo. Dijiste que necesitas una colección de colecciones de cadenas en cada fila para que el cuadro combinado pueda mostrar diferentes cadenas para diferentes filas. Sin embargo, para que un cuadro combinado muestre un conjunto de cadenas, solo necesita una colección de cadenas, por fila, no una colección de colección de cadenas.

Ahora, dado que necesita la colección de cadenas por fila, puede estar pensando que necesitaría la colección de la colección de cadenas.

¿Es correcto entender su pregunta? Si es así, entonces su mención de la colección de la colección de cadenas es incorrecta.

Lo que realmente necesita es una colección de StatOperations en la que cada StatOperation debe tener una colección de cadenas. Así es exactamente como lo tenía como se muestra en sus clases anteriores.

Para avanzar, le sugiero que edite su pregunta y señale dónde estaba exactamente atrapado después de arreglar el enlace como lo sugiere AndyG.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top