Pergunta

Situação:

Eu criei um DataGrid em XAML eo ItemsSource é binded a uma ObservableCollection de uma certa classe que contém propriedades. Em seguida, em C #, eu criar um DataGridTextColumn e um DataGridComboBoxColumn e binded estes para as propriedades dos objectos no interior do ObservableCollection. Posso vincular a DataGridComboBoxColumn a uma simples colecção mas o que eu quero fazer é vinculá-lo a uma coleção de coleções de cordas de modo que para cada linha da caixa de combinação dentro do DataGrid tem uma coleção diferente de string. Eu não conseguiram fazê-lo ...

Pergunta:

Como posso vincular o DataGridCombBoxColumn para que eu possa ter uma coleção diferente de cordas para cada linha deste tipo de coluna?

Código de exemplo:

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

Qualquer ajuda seria muito apreciada!

Notas:

Ok, então depois de ler as duas primeiras respostas notei algo. Minha ligação não é realmente certo! Agora, o que eu quero fazer é algo semelhante ao que AndyG proposta:

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

erro: "Não é possível converter implicitamente tipo 'System.Windows.Data.Binding' para 'System.Collections.IEnumerable'"

Como pode o ItemsSource ser vinculado a Data?

Foi útil?

Solução

Em primeiro lugar, isso deve ser fácil ... em segundo lugar, por que você está construindo (e obrigatório) colunas em C #? Eek.

XAML (estou usando uma grade regular porque eu sou preguiçoso):

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

Os resultados:

WPF grade com opções de caixa de dinâmica de combinação http: // www.singingeels.com/Articles/Articles/UserImage.aspx?ImageID=b1e3f880-c278-4d2b-bcc2-8ad390591200

Outras dicas

Eu acho que o erro está na forma como você fez a sua ligação. Quando você definir uma coluna, a ligação está relacionada com o objeto que é representado por uma linha particular. Então, como eu entendo, você tem um StatsOperation para cada linha, então a coluna de TextBox é obrigado a operação, que é a forma como você tem, ea coluna ComboBox ItemsSource deve ser ligado a uma Collection. Agora parece que ele está ligado a uma Collection<Collection<string>>.

Eu não tenho definido colunas em code-behind antes, então aqui está um exemplo em XAML. Eu encontrei ComboBoxColumn pode ser, por vezes, complicado por isso eu mostrei como você pode ter um combobox na coluna usando qualquer um TemplateColumn ou um ComboBoxColumn. Eu tenho cópia colado de meu próprio código para apenas substituir 'dg' com 'WPFToolkit' no seu 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>

Estou assumindo que o funcionamento é o item selecionado, os dados são os itens para escolher, e que o DataGrid está vinculado a uma coleção de StatsOperation. Boa sorte!

Para corrigir o seu ItemsSource Encadernação uso de erro do formulário:

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

Você, obviamente, não pode fazer isso no intializer assim você vai ter que mover suas declarações em torno de um pouco, mas que deve ter o cuidado de que o erro na sua atualização.

Editar Eu sinto muito, eu sou pouco lento no midnights :). Aqui está uma resposta atualizado. Parece ótimo artigo de Vincent Sibal WPF DataGrid - DataGridComboBoxColumn v1 Intro responde a sua pergunta. Não é?

Parcial - Eu acho que há uma confusão no que você está dizendo. Você disse que você precisa de uma coleção de coleção de cadeias de caracteres em cada linha de modo que a caixa de combinação poderia mostrar cordas diferentes para diferentes linhas. No entanto, para uma caixa de combinação para mostrar um conjunto de cordas, você só precisa de um conjunto de cordas, por linha, não uma coleção de coleção de strings.

Agora, desde que você precisa a coleta de cordas por linha que você pode estar pensando que você precisaria coleção de coleção de strings.

É o meu entendimento da sua pergunta correta? Se assim for, então a sua menção de coleção de coleção de cordas é errado.

O que você realmente precisa é uma coleção de StatOperations em que cada StatOperation deve ter uma coleção de strings. Isto é exatamente como você tinha como mostrado em suas classes acima.

Para fazer progressos, sugiro que você editar a sua pergunta e apontar onde exatamente você estava preso após a fixação da ligação como sugerido por AndyG.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top