Question

Situation:

J'ai créé un DataGrid en XAML et le ItemsSource est lié à un ObservableCollection d'une certaine classe contenant des propriétés. Ensuite, en C #, je crée un DataGridTextColumn et un DataGridComboBoxColumn et les lie aux propriétés des objets à l'intérieur de ObservableCollection. Je peux lier le DataGridComboBoxColumn à une collection simple, mais ce que je veux faire, c'est le lier à une collection de collections de chaînes afin que, pour chaque ligne, la ComboBox à l'intérieur du DataGrid ait une collection différente de chaînes. Je n'ai pas réussi à le faire ...

Question:

Comment puis-je lier le DataGridCombBoxColumn afin d'avoir une collection de chaînes différente pour chaque ligne de ce type de colonne?

Exemple de code:

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_
};
//...

Toute aide serait grandement appréciée!

Notes:

D'accord, donc après avoir lu les deux premières réponses, j'ai remarqué quelque chose. Ma liaison n'est vraiment pas correcte! Maintenant, ce que je veux faire est quelque chose de similaire à ce que AndyG a proposé:

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

Erreur: & "Impossible de convertir implicitement le type" System.Windows.Data.Binding "en" System.Collections.IEnumerable ". &";

Comment le ItemsSource peut-il être lié aux données?

Était-ce utile?

La solution

Premièrement, cela devrait être facile ... deuxièmement, pourquoi construisez-vous (et liez-vous) des colonnes en C #? Eek.

XAML (j'utilise une grille classique car je suis paresseux):

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

Les résultats:

Grille WPF avec choix dynamique de combo box http: // www.singingeels.com/Articles/Articles/UserImage.aspx?ImageID=b1e3f880-c278-4d2b-bcc2-8ad390591200

Autres conseils

Je pense que l’erreur est dans la manière dont vous avez réalisé votre engagement. Lorsque vous définissez une colonne, la liaison est liée à l'objet représenté par une ligne particulière. Par conséquent, si j'ai bien compris, vous avez une opération StatsOperation pour chaque ligne. La colonne TextBox est donc liée à l'opération, comme vous l'avez, et la colonne ComboBox ItemsSource doit être liée à une collection. À l'heure actuelle, il semble que cela soit lié à un Collection<Collection<string>>.

Je n'ai pas défini de colonnes dans code-behind auparavant. Voici donc un exemple en XAML. J'ai trouvé que ComboBoxColumn peut être difficile parfois, alors j'ai montré comment vous pouvez avoir une liste déroulante dans la colonne en utilisant soit un TemplateColumn, soit un ComboBoxColumn. J'ai copié-collé à partir de mon propre code, remplacez simplement "dg" par "WPFToolkit" dans votre cas:

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

Je suppose que Operation est l'élément sélectionné, que Data est les éléments à sélectionner et que votre DataGrid est lié à une collection de StatsOperation. Bonne chance!

Pour corriger votre erreur de liaison ItemsSource, utilisez le formulaire suivant:

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

Vous ne pouvez évidemment pas faire cela dans intializer, vous devez donc déplacer un peu vos déclarations, mais cela devrait résoudre cette erreur dans votre mise à jour.

MODIFIER Je suis désolé, je suis un peu lent au milieu des nuits :). Voici une réponse mise à jour. Cela semble être un excellent article de Vincent Sibal WPF DataGrid - DataGridComboBoxColumn v1 Intro répond à votre question. Le fait-il?

Partiel - Je pense qu'il y a une confusion dans ce que vous dites. Vous avez dit que vous aviez besoin d'une collection de chaînes dans chaque ligne pour que la liste déroulante puisse afficher différentes chaînes pour différentes lignes. Toutefois, pour qu'une zone de liste déroulante affiche un ensemble de chaînes, vous avez uniquement besoin d'une collection de chaînes, par ligne, et non d'une collection de chaînes.

Maintenant que vous avez besoin de la collection de chaînes par ligne, vous pensez peut-être que vous auriez besoin d'une collection de collection de chaînes.

Est-ce que ma compréhension de votre question est correcte? Dans ce cas, votre mention de collection ou collection de chaînes est fausse.

Ce dont vous avez réellement besoin est une collection de StatOperations dans laquelle chaque StatOperation devrait avoir une collection de chaînes. C’est exactement ce que vous avez fait, comme indiqué dans vos cours ci-dessus.

Pour progresser, je vous suggère de modifier votre question et d'indiquer où vous étiez coincé après avoir corrigé la reliure comme suggéré par AndyG.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top