Como posso ligar Wpf DataGridColumn a um objeto?

votos
5

Eu quero ligar as colunas do meu WPF DataGrid com alguns objetos em um dicionário como este:

Binding Path = Objetos [i]

onde os objetos é meu dicionário de objetos, de modo que cada célula vai representar um elemento de objeto. Como eu posso fazer isso?

Suponho que eu preciso para criar um modelo para o meu celular, o que eu fiz, mas como obter o resultado de coluna obrigatório em meu modelo? Eu sei que, por padrão o conteúdo de um DataGridCell é um TextBlock e é propriedade de texto é definido através do resultado de ligação da coluna, mas se esse resultado é um objeto Eu acho que eu tenho que criar um ContentTemplate. Como posso fazer isso, pois as coisas que eu tentei não está exibindo nada.

Aqui está o que eu tentei:

<Style x:Key=CellStyle TargetType={x:Type dg:DataGridCell}>
    <Setter Property=Template> ---it should realy be ContentTemplate?
      <Setter.Value>
        <ControlTemplate>
          <controls:DataGridCellControl CurrentObject={Binding }/> -- I would expect to get the object like this for this column path : Path=Objects[i] but is not working
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

Então, para me tornar completamente claro, eu quero entrar em CurrentObject propriedade de meu DataGridCellControl o objeto atual que deve resultar se eu definir a ligação em minha grade de dados como este caminho = Objetos [i] coluna.

Obrigado por qualquer sugestão,

John.

Publicado 19/05/2009 em 18:16
fonte usuário
Em outras línguas...                            


2 respostas

votos
0

Fiz algumas classes auxiliares para que eu pudesse usar o DataGrid como uma espécie de DataTable. Em outras palavras, eu queria que a formatação, classificação e olhar polido do DataGrid sem ter de pré-fab algumas classes de antemão. A principal razão que eu queria era para uma suíte de testes, eu queria ser capaz de criar um número arbitrário de colunas e em tempo de execução. Aqui está o que eu tenho

public class DataRow
{
    internal List<object> Items = new List<object>();

    public object this[string value]
    {
        get { return Items[Convert.ToInt32(value)]; }
    }

    public string GetString(int index)
    {
        return Items[index].ToString();
    }

    public object GetObject(int index)
    {
        return Items[index];
    }

    public DataRow(params object[] values)
    {
        if (values == null || values.Length < 1)
            throw new Exception("You must pass in some values");

        Items.AddRange(values);            
    }
}  

public class GridConstructor
{
    public List<DataRow> Rows = new List<DataRow>();
    private DataRow headers;

    public GridConstructor(DataRow head)
    {
        headers = head;
    }

    public void BuildInto(DataGrid grid)
    {
        grid.AutoGenerateColumns = false;
        grid.Columns.Clear();
        int totalCols = 0;

        Type headType = headers.GetType();

        for (int i = 0; i < headers.Items.Count; i++)
        {
            grid.Columns.Add(GetCol(headers.GetString(i), String.Concat("[", i.ToString(),"]")));
            totalCols++;
        }                     

        int finalWidth = totalCols * (int)grid.ColumnWidth.Value + 15;
        grid.Width = finalWidth;

        grid.ItemsSource = Rows;
    }

    private DataGridTextColumn GetCol(string header, string binding)
    {
        DataGridTextColumn col = new DataGridTextColumn();
        col.IsReadOnly = true;            
        col.Header = header;
        col.Binding = new Binding(binding);

        return col;
    }

    public DataGrid Create(int colSize)
    {
        DataGrid grid = new DataGrid();
        grid.ColumnWidth = colSize;
        grid.CanUserAddRows = false;
        grid.AlternationCount = 2;
        BuildInto(grid);
        return grid;
    }
}

Colocar isso em conjunto, este é um uso de exemplo:

void SimpleTest_Loaded(object sender, RoutedEventArgs e)
    {            
        DataRow headers = new DataRow("Level", "Weapon Type", "vs None", "vs Leather", "vs Studded", "vs Brigandine");            
        GridConstructor gridConstructor = new GridConstructor(headers);            

        var weaponType = "Slash";
        for (int level = 1; level < 10; level++)
        {
            int damage = DiceCup.RollMulti(8, level);
            int damCloth = damage - DiceCup.RollMulti(2, level);
            int damLeather = damage - DiceCup.RollMulti(3, level);
            int damStudded = damage - DiceCup.RollMulti(4, level);
            int damBrigandine = damage - DiceCup.RollMulti(5, level);

            DataRow row = new DataRow(level, weaponType, damage, damCloth, damLeather, damStudded, damBrigandine);
            gridConstructor.Rows.Add(row);                
        }

        //Create the grid.
        var grid = gridConstructor.Create(100);


        //Create a chart.
        Chart chart = new Chart();
        chart.Height = 200;
        chart.LegendTitle = "Legend";
        chart.Title = "Slash vs Armor Types";                       
        chart.DataContext = gridConstructor.Rows;            


        //Create our series, or lines.
        LineSeries slashVsNone = new LineSeries();
        slashVsNone.Title = "vs None";
        slashVsNone.DependentValueBinding = new Binding("[2]");
        slashVsNone.IndependentValueBinding = new Binding("[0]");
        slashVsNone.ItemsSource = gridConstructor.Rows;            
        chart.Series.Add(slashVsNone);

        //Presentation is a stackpanel on the page.            
        presentation.Children.Add(grid);
        presentation.Children.Add(chart);             
    }

E a saída:

texto alt http://quiteabnormal.com/images/codeSample.jpg

Por favor, note que a coloração da grade é de estilos universais definidos na página. Se você usar o método GridConstructor.BuildInto () você pode especificar uma grade que você se pré-formatado no Blend ou algo assim.

Apenas uma coisa, o GridConstructor faz algumas suposições sobre as definições iniciais da coluna. Você pode alterar a classe para torná-lo mais personalizável, se quiser, mas isso é o que eu precisava, então eu queria ser capaz de fazê-lo sem problemas.

Respondeu 02/09/2009 em 01:35
fonte usuário

votos
0

Tente isto:

<ListView x:Name="listViewUsers" SelectionMode="Single" 
                              ItemsSource="{Binding ElementName=window1, Path=Users, Mode=TwoWay}" MouseDoubleClick="listViewUsers_MouseDoubleClick">
                        <ListView.View>
                            <GridView x:Name="gridViewUsers" AllowsColumnReorder="False">
                                <GridViewColumn>
                                    <GridViewColumn.CellTemplate>
                                        <DataTemplate>
                                            <Image Source="{Binding Path=IsAdministrator, Converter={StaticResource boolToImage}, ConverterParameter='Images/admin18.gif|Images/user18.gif'}" />
                                        </DataTemplate>
                                    </GridViewColumn.CellTemplate>
                                </GridViewColumn>
                                <GridViewColumn Header="User Name" DisplayMemberBinding="{Binding Path=UserName}" Width="140" />
                                <GridViewColumn Header="Full Name" DisplayMemberBinding="{Binding Path=FullName}" Width="140" />
                                <GridViewColumn Header="Phone Number" DisplayMemberBinding="{Binding Path=PhoneNumber}" Width="110" />
                                <GridViewColumn Header="Access Type" DisplayMemberBinding="{Binding Path=AccessType}" Width="110">
                                </GridViewColumn>
                                <GridViewColumn>
                                    <GridViewColumn.CellTemplate>
                                        <DataTemplate>
                                            <Image Cursor="Hand" ToolTip="Delete User" Stretch="None" Source="Images/trash12.gif" MouseUp="DeleteUser" />
                                        </DataTemplate>
                                    </GridViewColumn.CellTemplate>
                                </GridViewColumn>
                            </GridView>
                        </ListView.View>
                    </ListView>

Onde em ItemsSource = "{Binding ElementName = window1, Path = Usuários, Mode = TwoWay}"

  • ElementName é o nome da janela em XAML (basta adicionar x: Name = "window1" à tag Janela como com qualquer outro ontrol.

  • Usuários é uma lista, deve trabalhar o mesmo com dicionário

  • Mode = TwoWay significa que se a grade é modificado, a lista vai ser modificado também, e vice-versa (ligação em dois sentidos)

EDITAR:

Tente isto:

XAML:

<ListView x:Name="listViewTest" ItemsSource="{Binding}">
<ListView.View>
    <GridView x:Name="gridViewTest">

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

C #:

public class TheClass
    {
        public int Col1, Col2, Col3; 
        public Dictionary<int, OtherColumns> otherColumns = new Dictionary<int,OtherColumns>();
    }

    public class OtherColumns
    {
        public string ColumnName;
        public int Value;
    }

E chamar esse método sob Window_Loaded:

private void PopulateListView()
        {
            TheClass c = new TheClass();

            c.Col1 = 10;
            c.Col2 = 20;
            c.Col3 = 30;


            c.otherColumns.Add(0, new OtherColumns() { ColumnName = "Col4", Value = 40 });
            c.otherColumns.Add(1, new OtherColumns() { ColumnName = "Col5", Value = 50 });
            c.otherColumns.Add(3, new OtherColumns() { ColumnName = "Col6", Value = 60 });

            DataTable table = new DataTable();

// adding regular columns
            table.Columns.Add("Col1", typeof(int));
            table.Columns.Add("Col2", typeof(int));
            table.Columns.Add("Col3", typeof(int));

// adding dynamic columns
            foreach (KeyValuePair<int, OtherColumns> pair in c.otherColumns)
            {
                table.Columns.Add(pair.Value.ColumnName, typeof(int));
            }

            DataRow row = table.NewRow();

// adding regular column values to the DataTable
            row["Col1"] = c.Col1;
            row["Col2"] = c.Col2;
            row["Col3"] = c.Col3;

// adding dynamic column values to the DataTable
            foreach (KeyValuePair<int, OtherColumns> pair in c.otherColumns)
            {
                row[pair.Value.ColumnName] = pair.Value.Value;
            }

            table.Rows.Add(row);

            // Start binding the table.
            gridViewTest.Columns.Clear();

            System.Windows.Controls.GridViewColumn gvc;
            Binding binding;

            foreach (DataColumn column in table.Columns)
            {
                gvc = new System.Windows.Controls.GridViewColumn();
                binding = new System.Windows.Data.Binding();
                binding.Path = new PropertyPath(column.ColumnName);
                binding.Mode = BindingMode.OneWay;
                gvc.Header = column.Caption;
                gvc.DisplayMemberBinding = binding;
                gridViewTest.Columns.Add(gvc);
            }

            listViewTest.DataContext = table;
        }

Eu não estou dizendo que é a melhor solução, mas pode ajudar. Avise-se me.

Respondeu 19/05/2009 em 18:41
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more