Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
below example in web application how to write like this in wpf datagrid

What I have tried:

foreach (GridViewRow Dr in gdvResponsibility.Rows)
{
   Action = 0;
   CheckBox chkEdit = (CheckBox)Dr.FindControl("chkEdit");
   CheckBox chkView = (CheckBox)Dr.FindControl("chkView");
   Edit = Convert.ToInt16(gdvResponsibility.DataKeys[Dr.RowIndex].Values[2].ToString());
   View = Convert.ToInt16(gdvResponsibility.DataKeys[Dr.RowIndex].Values[3].ToString());

   if (chkEdit.Visible == false && chkView.Checked == true)
      Action = 2;
   else if (chkEdit.Checked == false && chkView.Checked == true)
      Action = 2;
   else if (chkEdit.Checked == true && chkView.Checked == true)
      Action = 3;
   else if (chkEdit.Checked == true && chkView.Checked == false)
      Action = 1;
   else if (chkEdit.Checked == false && chkView.Checked == false)
      Action = 0;

   sQry[i++] = " INSERT INTO usermenu_mapping (UserId,MenuId,Action)VALUES('" + ddlUser.SelectedValue + "'," + gdvResponsibility.DataKeys[Dr.RowIndex].Values[0].ToString() + "," + Action + " ) ON DUPLICATE KEY UPDATE Action=" + Action;
}
Posted
Updated 7-Jul-18 23:35pm
v2

1 solution

The power of WPF over WinForms is in a number of areas, one of those is Data Binding[^]. Once you master databinding you won't want to work directly with controls as it is far far simpler.

So with that in mind, Below is a solution that demonstrates how to work with the data.

WPF Data binding uses a notification system for when data changes. For individual objects/classes, is defind with the INotifyPropertyChanged interface. To simplify the implementation, I use the following base class:
C#
public abstract class ObservableBase : INotifyPropertyChanged
{
    public void Set<TValue>(ref TValue field, TValue newValue,
                            [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<TValue>.Default
                                    .Equals(field, default(TValue)) ||
                                            !field.Equals(newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

1. First we need to model the data:
C#
public class UserMenuMapping : ObservableBase
{
    private long userId;
    public long UserId
    {
        get => userId;
        set => Set(ref userId, value);
    }

    private int menuId;
    public int MenuId
    {
        get => menuId;
        set => Set(ref menuId, value);
    }

    private bool canEdit;
    public bool CanEdit
    {
        get => canEdit;
        set => Set(ref canEdit, value);
    }

    private bool canView;
    public bool CanView
    {
        get => canView;
        set => Set(ref canView, value);
    }

    public int Action()
    {
        if (!CanEdit && CanView) return 2;
        else if (CanEdit && CanView) return 3;
        else if (CanEdit && !CanView) return 1;
        return 0;
    }
}

2. Now we need to set up the data in our code behind.

For Collections of objects, WPF has a special List collection class called ObservableCollection which implements the INotifyCollectionChanged & INotifyPropertyChanged interfaces for WPF data binding.
C#
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this; // bind to code behind
        MockData(); // Load the data to be displayed
    }

    private void MockData()
    {
        Data.Clear(); // always use clear not new to not break the binding

        for (int i = 0; i < 10; i++)
        {
            Data.Add(new UserMenuMapping
            {
                UserId = 10000 + i,
                MenuId = 10+i,
                CanEdit = true,
                CanView = true
            });
        }
    }

    public ObservableCollection<UserMenuMapping> Data { get; }
        = new ObservableCollection<UserMenuMapping>();

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        foreach (var row in Data)
        {
            // Save to DB
            Debug.WriteLine($"User:{row.UserId} | Menu:{row.MenuId} | Action: {row.Action()}");
        }
    }
}

Above we bind the XAML to the code behind. This will expose the Data collection property to the UI. Now we can bind the DataGrid to allow the data to be edited:
XML
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <DataGrid ItemsSource="{Binding Data}"
                GridLinesVisibility="None"
                AlternatingRowBackground="GhostWhite" AlternationCount="1"
                ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                AutoGenerateColumns="False"
                RowDetailsVisibilityMode="VisibleWhenSelected"
                VirtualizingPanel.ScrollUnit="Pixel">
        <DataGrid.Columns>
            <DataGridTextColumn Header="User ID" Binding="{Binding UserId}"/>
            <DataGridTextColumn Header="Menu ID" Binding="{Binding MenuId}"/>
            <DataGridCheckBoxColumn Header="Can Edit" Binding="{Binding CanEdit}"/>
            <DataGridCheckBoxColumn Header="Can View" Binding="{Binding CanView}"/>
        </DataGrid.Columns>
    </DataGrid>
    <Button Content="SAVE" Grid.Row="1"
            Click="Button_Click"
            HorizontalAlignment="Center"
            Padding="10 5" Margin="10"/>
</Grid>

As you can see in the Button_Click you don't have to do anything fancy to read back any of the changes.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900