Pochmurnik
Pochmurnik

Reputation: 828

WPF DataGrid, getting cell value

I need to get cell value from SelectedItem of DataGrid.

Here is DataGrid XAML code:

<DataGrid CanUserReorderColumns="false" CanUserAddRows="False" AutoGenerateColumns="False" Height="180" HorizontalAlignment="Left" Margin="6,11,0,0" Name="dataGridCards" VerticalAlignment="Top" Width="288" SelectionChanged="dataGridCards_SelectionChanged">
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="Card ID" Binding="{Binding cardID}" IsReadOnly="True"/>
                        <DataGridTextColumn Header="Card Name" Binding="{Binding cardName}" IsReadOnly="True"/>
                        <DataGridTextColumn Header="Set Mark" Binding="{Binding setMark}" IsReadOnly="True" Width="*"/>
                    </DataGrid.Columns>
                </DataGrid>

I blocked column reorder and used:

object row = dataGridCards.SelectedItem;
cardName = (dataGridCards.SelectedCells[1].Column.GetCellContent(row) as TextBlock).Text;

DataGrid displays join of two tables. I really don't like this solution, I prefer not to block reordering. How can I get cell value without block reordering? Do I need to define some patterns for DataGrid rows?

Upvotes: 0

Views: 4023

Answers (2)

Pochmurnik
Pochmurnik

Reputation: 828

I prepared a class to populate dataGrid:

class RowCardSet
{
    private int cardID;
    private String cardName;
    private String setMark;

    public RowCardSet(int cardID, String cardName, String setMark)
    {
        this.cardID = cardID;
        this.cardName = cardName;
        this.setMark = setMark;
    }

    public int CardID
    {
        get { return this.cardID; }
        set { this.cardID = value; }
    }

    public String CardName
    {
        get { return this.cardName; }
        set { this.cardName = value; }
    }

    public String SetMark
    {
        get { return this.setMark; }
        set { this.setMark = value; }
    }
}

In that case I also needed to change Binding in dataGrid. From cardID, cardName, setMark to CardID, CardName and SetMark:

<DataGrid.Columns>
  <DataGridTextColumn Header="Card ID" Binding="{Binding CardID}" IsReadOnly="True"/>
  <DataGridTextColumn Header="Card Name" Binding="{Binding CardName}" IsReadOnly="True"/>
  <DataGridTextColumn Header="Set Mark" Binding="{Binding SetMark}" IsReadOnly="True" Width="*"/>
</DataGrid.Columns>

Here is the query to populate dataGrid:

public static List<RowCardSet> GetCardSetList(int setID, DataContext dataContext)
    {
        return (from cardItem in dataContext.Cards
                join setItem in dataContext.Sets
                on cardItem.setID equals setItem.setID
                where cardItem.setID == setID
                select new RowCardSet(
                    cardItem.cardID,
                    cardItem.cardName,
                    setItem.setMark)).ToList();
    }

So now I can populate using this method: dataGridCards.ItemsSource = Queries.GetCardSetList(setID, dataContext);

and getting a specific value looks like this:

String cardName = ((RowCardSet)dataGridCards.SelectedItem).CardName.ToString();

Upvotes: 0

Gary Wright
Gary Wright

Reputation: 2469

You can query the column header to find the current index, then use that:

object row = dataGridCards.SelectedItem;
int columnIndex = dataGridCards.Columns.Single(c => c.Header.Equals("Card Name")).DisplayIndex;
String cardName = (dataGridCards.SelectedCells[columnIndex].Column.GetCellContent(row) as TextBlock).Text;

Upvotes: 2

Related Questions