Hunv
Hunv

Reputation: 413

SelectedItem Binding in Datagrid WPF

I have a Datagrid, that shows Columns, that are added by setting the ItemsSource-Property via Code. I also have two columns, that are added by XAML (a Button and a combination of Image and Button in a Grid). Now I am editing some cells and want to read them. In Windows Forms it was possible to read specific cells but this is not possible or recommended in WPF, I read. So I want to use a SelectedItem-Binding. My Problem is, that the SelectedItem is always null. Maybe there is a problem with the Datagrid because of the "mixed adding" of columns or I am doing something wrong.

Here is the part of my Code:

XAML:

 <DataGrid AutoGenerateColumns="True" Margin="12,162,12,12" Name="dgExisting" CanUserAddRows="False" RowHeight="24" VerticalGridLinesBrush="#50000000" HorizontalGridLinesBrush="#50000000" SelectionMode="Single" CellStyle="{StaticResource DataGridCell_Centering}" CellEditEnding="dgExisting_CellEditEnding" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">            
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Password" Width="60" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>                        
                    <DataTemplate>
                        <Button Style="{StaticResource Flat}" Click="btnDgChangePassword_Click">
                            <Grid>
                                <Image Source="{Binding imgStatus}" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                                <Label Content="{Binding PasswordState}" Margin="16,-5,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Height="25" />
                            </Grid>
                        </Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Delete" Width="50" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Click="btnDgRemove_Click" Style="{StaticResource Flat}">
                            <Image Source="Images/redcross16.png" />
                        </Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

And the Code how I add the columns by code:

//Create Table for Gridview
DataTable dtList = new DataTable();
dtList.Columns.Add(new DataColumn("Username"));
dtList.Columns.Add(new DataColumn("PasswordState"));
dtList.Columns.Add(new DataColumn("Domain"));
dtList.Columns.Add(new DataColumn("Description"));
dtList.Columns.Add(new DataColumn("id"));

foreach (UserCredential uc in credentialList)
{
    DataRow dR = dtList.NewRow();                
    dR["Username"] = uc.getUsername();
    dR["PasswordState"] = (uc.getPassword().Length > 0 ? "yes":"no");
    dR["Domain"] = uc.getDomain();
    dR["Description"] = uc.getDescription();
    dR["id"] = uc.getId();

    dtList.Rows.Add(dR);
}

dtList.Columns.Add("imgStatus");

for (int i = 0; i < dtList.Rows.Count; i++)
{
    dtList.Rows[i]["imgStatus"] = (dtList.Rows[i]["PasswordState"].ToString() == "yes" ? "Images/key16.png" : "");
}

dgExisting.ItemsSource = dtList.DefaultView;
dgExisting.Columns[getColumnId("Password")].DisplayIndex = 2; //reorder Key-Image
dgExisting.Columns[getColumnId("PasswordState")].Visibility = System.Windows.Visibility.Hidden; 
dgExisting.Columns[getColumnId("imgStatus")].Visibility = System.Windows.Visibility.Hidden; 
dgExisting.Columns[getColumnId("id")].Visibility = System.Windows.Visibility.Hidden; 

Upvotes: 0

Views: 2697

Answers (1)

Gus
Gus

Reputation: 649

In your C# code you are not creating a binding to the DataGrid's item source.

dgExisting.ItemsSource = dtList.DefaultView;

is NOT a binding. This is why your SelectedItem always null in your XAML binding. To create a binding in code you would need to do something like:

var binding = new Binding("ItemsSource");
binding.Source = dtList.DefaultView;
dgExisting.SetBinding(DataGrid.ItemsSourceProperty, binding);

Setting bindings WPF in C# is a bit of a smell. There may be a reason that you have to do it. But, I would suggest redesigning your application to better follow the MVVM pattern so that you can just set your binding in XAML.

Upvotes: 1

Related Questions