0
votes

I am trying to display in a textblock all the hostnames from selected rows in a datagrid.

The datagrid ItemsSource is an observable collection of systems pulled from an XML file.

I can successfully bind the hostNameList.Text to a single selected item in the datagrid with binding, but I don't know how to how to display when multiple rows are selected. The datagrid can vary in how many systems it lists so I can't predict and just have a certain number of textblocks.

I've come close in getting this achieved but the issue is I have to change selections in the datagrid for the hostNameList.Text to update. I know that is what the selectionChanged Event does but other events like MouseLeftButtonDown, etc behave in a similar fashion. I'd like it to update immediately like when it is bound to a single row selectedItem.

Any ideas?

Below is the code I have where all works except it will not update until the selection changes in the datagrid.

Xaml:

<DataGrid x:Name="ClientDataGrid"
      AutoGenerateColumns="False"
      AlternatingRowBackground="{StaticResource lightGreenBrush}"
      AlternationCount="2"
      CanUserAddRows="False"
      SelectionChanged="ClientDataGrid_SelectionChanged" >
<DataGrid.Columns>
    <DataGridCheckBoxColumn IsReadOnly="False"
                            Binding="{Binding IsChecked}" >
        <DataGridCheckBoxColumn.Header>
            <CheckBox x:Name="checkSelectAll"
                      Checked="checkSelectAll_Checked"
                      Unchecked="checkSelectAll_Unchecked" />
        </DataGridCheckBoxColumn.Header>
    </DataGridCheckBoxColumn>
    <DataGridTemplateColumn Header="Status">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal"
                            HorizontalAlignment="Center" >
                    <Image Source="{Binding Path=Status, Converter={StaticResource statusImageConverter }}"
                           ToolTip="{Binding Path=Status}" />
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="Hostname"
                        Binding="{Binding Hostname}"
                        IsReadOnly="True" />
    <DataGridTextColumn Header="IP"
                        Binding="{Binding IP}"
                        IsReadOnly="True" />
    <DataGridTextColumn Header="Subnet Mask"
                        Binding="{Binding SubnetMask}"
                        IsReadOnly="True" />
    <DataGridTextColumn Header="Gateway"
                        Binding="{Binding Gateway}"
                        IsReadOnly="True" />
</DataGrid.Columns>

Code behind:

private ClientDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // Add all names to a list
    List<string> clientsSelected = new List<string>();

    foreach (Clients c in ClientDataGrid.ItemsSource)
    {
        if (c.IsChecked == true)
        {
            clientsSelected.Add(c.Hostname);
        }
    }

    //Build string of hostnames that are changing and set to textbox text
    hostNameList.Text = string.Join(", ", clientsSelected);
}
2

2 Answers

0
votes

You could add an event handler for the MouseUp event on the DataGrid rows:

<DataGrid.RowStyle>
    <EventSetter Event="MouseUp" Handler="DataGrid_MouseUp" />
</DataGrid.RowStyle>

Code behind (using DataGrid's SelectedItems property):

private DataGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
    // Add all names to a list
    List<string> clientsSelected = new List<string>();

    foreach (Clients c in ClientDataGrid.SelectedItems)
    {
        clientsSelected.Add(c.Hostname);
    }

    //Build string of hostnames that are changing and set to textbox text
    hostNameList.Text = string.Join(", ", clientsSelected);
}
0
votes

OK. I figured out something that worked for me. I ended up using a DataGridTemplateColumn. Thanks again for those who responded with suggestions. Much appreciated! Note when I tried using the SelectedItems property it always just listed the last checkbox selected so I changed back to itemssource and that worked.

Xaml:

<DataGrid x:Name="ClientDataGrid"
      AutoGenerateColumns="False"
      AlternatingRowBackground="{StaticResource lightGreenBrush}"
      AlternationCount="2"
      CanUserAddRows="False"
      SelectionChanged="ClientDataGrid_SelectionChanged" >
<DataGrid.Columns>
    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}"
                          Checked="CheckBox_Checked" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTemplateColumn Header="Status">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal"
                            HorizontalAlignment="Center" >
                    <Image Source="{Binding Path=Status, Converter={StaticResource statusImageConverter }}"
                           ToolTip="{Binding Path=Status}" />
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="Hostname"
                        Binding="{Binding Hostname}"
                        IsReadOnly="True" />
    <DataGridTextColumn Header="IP"
                        Binding="{Binding IP}"
                        IsReadOnly="True" />
    <DataGridTextColumn Header="Subnet Mask"
                        Binding="{Binding SubnetMask}"
                        IsReadOnly="True" />
    <DataGridTextColumn Header="Gateway"
                        Binding="{Binding Gateway}"
                        IsReadOnly="True" />
</DataGrid.Columns>

Code Behind:

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        // Add all names to a list
        List<string> clientsSelected = new List<string>();

        foreach (PrairieDeskClients client in prairieDeskClientDataGridConfigurationStep1.ItemsSource)
        {
            if (client.IsChecked == true)
            {
                clientsSelected.Add(client.Hostname);
            }
        }

        //Build string of hostnames that are changing
        applyChangesToTheseClients.Text = string.Join(", ", clientsSelected);
    }