Search code examples
wpfdatagrid

WPF binding datagrid checkbox


I'm newbie to WPF programming...

I want to populate DataGrid with checkbox for each unique application from a given list, where technician can select application(s) for each device of its choice, and once he/she clicks on 'submit' button...tool would create a csv for the device which would later used for application mapping...

here is my xaml.

$Appname = 'App1', 'App2', 'App3'
[xml]$xaml= @"
<Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Application Deployment Staging" Height="672.607" Width="905.517">
   <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="368*"/>
            <ColumnDefinition Width="425*"/>
        </Grid.ColumnDefinitions>
        <TextBox Name="TXTDeviceName" HorizontalAlignment="Left" Height="22" Margin="81,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="194"/>
        <GroupBox Name="Grpbx01" Header="Enter Device Name" HorizontalAlignment="Left" Height="70" Margin="33,16,0,0" VerticalAlignment="Top" Width="310" FontWeight="Bold"/>
        <GroupBox Name="Grpbx02" Header="Available Applications" HorizontalAlignment="Left" Height="456" Margin="34,100,0,0" VerticalAlignment="Top" Width="810" Grid.ColumnSpan="2">
            <DataGrid Name="Datagrd1" HorizontalAlignment="Left" Height="412" Margin="9,16,0,0" VerticalAlignment="Top" Width="776">
                <DataGrid.Columns>



                 </DataGrid.Columns>
             </DataGrid>
        </GroupBox>
        <Button Name="btn01" Content="Submit" Grid.Column="1" HorizontalAlignment="Left" Margin="226.4,578,0,0" VerticalAlignment="Top" Width="90" Height="27" FontWeight="Bold">
            <Button.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF77CAAB" Offset="0.771"/>
                    <GradientStop Color="#FFFAFAFA" Offset="0.003"/>
                </LinearGradientBrush>
            </Button.Background>
        </Button>
        <Button Name="btn02" Content="Cancel" Grid.Column="1" HorizontalAlignment="Left" Margin="337.4,576,0,0" VerticalAlignment="Top" Width="90" Height="27" FontWeight="Bold">
            <Button.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF98B1A8" Offset="0.771"/>
                    <GradientStop Color="#FFFAFAFA" Offset="0.003"/>
                </LinearGradientBrush>
            </Button.Background>
        </Button>
    </Grid>
</Window>
"@

# Add assemblie
Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase, System.DirectoryServices, system.Drawing, System.Windows.Forms, WindowsFormsIntegration

$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Form=[Windows.Markup.XamlReader]::Load( $reader )
$xaml.SelectNodes("//*[@Name]") | %{ Set-Variable -Name "$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop }

$Form.ShowDialog() | Out-Null

Solution

  • Solution 1

    If I understand your problem correct you need to add a class like MyApplicationList at first. Here are an example:

    public class MyApplicationList
    {
        public bool IsSelected { get; set; }
        public string ApplicationName { get; set; }
    }
    

    Then you will create in your code an public property ObservableCollection (its a list).

    public ObservableCollection<MyApplicationList> ItemList { get; set; }
    

    Now create entries for the list and add them to the datagrid:

    public partial class MainWindow : Window
    {
        ...
        public ObservableCollection<MyApplicationList> ItemList { get; set; }
    
        public MainWindow()
        {
            InitializeComponent();
    
            ItemList = new ObservableCollection<MyApplicationList>();
            ItemList.Add(new MyApplicationList { ApplicationName = "App 1" });
            ItemList.Add(new MyApplicationList { ApplicationName = "App 2" });
            ItemList.Add(new MyApplicationList { ApplicationName = "App 3" });
    
            Datagrd1.ItemsSource = ItemList;
        }
        ...
    }
    

    In the XAML-Code you will modify the datagrid to this:

    <DataGrid x:Name="Datagrd1" 
              HorizontalAlignment="Left" 
              Margin="9,16,0,0" 
              VerticalAlignment="Top"
              AutoGenerateColumns="False"
              CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn Binding="{Binding IsSelected}"/>
            <DataGridTextColumn Binding="{Binding ApplicationName}" IsReadOnly="True" />
        </DataGrid.Columns>
    </DataGrid>
    

    The last step would now to add an event to the submit button:

    <Button Name="btn01" 
            Content="Submit" 
            HorizontalAlignment="Left"
            Margin="5,0,5,0" 
            VerticalAlignment="Top" 
            Width="90" 
            Height="27" 
            FontWeight="Bold"
            Click="btn01_Click">
        <Button.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF77CAAB" Offset="0.771"/>
                <GradientStop Color="#FFFAFAFA" Offset="0.003"/>
            </LinearGradientBrush>
        </Button.Background>
    </Button>
    

    In the event-handler you can check what the user has selected:

    private void btn01_Click(object sender, RoutedEventArgs e)
    {
        // Her you can check what the user has selectet and save in a file
        // Get the items from the ObservableCollection
    }
    

    This would be one way to do this as an beginner and hopefully it was understandable.

    Solution 2

    If you will do it nice you implement it as MVVM-patter. Then you do something like this: Create a new class like MainWindowViewModel.cs

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<MyApplicationList> ItemList { get; set; }
    
        public MainWindowViewModel()
        {
            ItemList = new ObservableCollection<MyApplicationList>();
            ItemList.Add(new MyApplicationList { ApplicationName = "App 1" });
            ItemList.Add(new MyApplicationList { ApplicationName = "App 2" });
            ItemList.Add(new MyApplicationList { ApplicationName = "App 3" });
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    In the class of the MainWindow set the MainWindowViewModel.cs to the DataContext property.

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
    

    Now bind the ObservableCollection in the MainWindow.xaml to the DataGrid:

    <DataGrid x:Name="Datagrd1" 
              HorizontalAlignment="Left" 
              Margin="9,16,0,0" 
              VerticalAlignment="Top"
              ItemsSource="{Binding ItemList}"
              AutoGenerateColumns="False"
              CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn Binding="{Binding IsSelected}"/>
            <DataGridTextColumn Binding="{Binding ApplicationName}" IsReadOnly="True" />
        </DataGrid.Columns>
    </DataGrid>
    

    The get the events of the buttons in the class MainWindowViewModel.cs, add a property in code behind and bind the command to the buttons.

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ICommand SubmitButtonPress { get; set; }
    
        public MainWindowViewModel()
        {
            ...
            SubmitButtonPress = new RelayCommand(SubmitButtonPressExecute, o => true);
            ...
        }
    
        private void SubmitButtonPressExecute(object o)
        {
            // Her you can check what the user has selectet and save in a file
            // Get the items from the ObservableCollection
        }
    }
    

    Her a like for an example for the class RelayCommand (C# Corner) Add the command to the buttons in MainWindow.xaml:

    ...
    <Button Name="btn01" 
            Content="Submit" 
            Command="{Binding SubmitButtonPress}"
            HorizontalAlignment="Left"                    
            Margin="5,0,5,0" 
            VerticalAlignment="Top" 
            Width="90" 
            Height="27" 
            FontWeight="Bold">
        <Button.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF77CAAB" Offset="0.771"/>
                <GradientStop Color="#FFFAFAFA" Offset="0.003"/>
            </LinearGradientBrush>
        </Button.Background>
    </Button>
    ...
    

    I hope this answer your question and helps.