Roxy'Pro
Roxy'Pro

Reputation: 4454

How to store ID from database object, to a checkbox in code behind WPF

I'm working on WPF application, and I have users, and ofcourse users has some kind of roles, in my case SUPERADMIN AND ADMIN, that roles are stored in table "Roles", One user could have 1 or more roles, so that means one or more checkbox can be selected on my form checkboxes that I generated dynamically on this way:

private void LoadRolesToStackPanel()
{
    try
    {
        var roles = RolesController.Instance.SelectAll();

        if (roles.Count > 0)
        {
            foreach (Role r in roles)
            {
                CheckBox cb = new CheckBox();

                //cb.Name = r.RoleId.ToString();

                cb.Content = r.Title.ToString();
                cb.FontSize = 15;
                stackRole.Children.Add(cb);
            }
        }


    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Later when I'm saving User I need to get ID from checked combobox because it is representing Role acctually, so I need to make insert to database with corresponding RoleId..

Here is how I took selected checkboxes on event SaveUser:

IEnumerable<CheckBox> selectedBoxes =
        from checkbox in this.stackRole.Children.OfType<CheckBox>()
        where checkbox.IsChecked.Value
        select checkbox;

foreach (CheckBox box in selectedBoxes)
{
// do something 
}

As it is possible to notice I can get Title from combobox because I said

cb.Content = r.Title.ToString();

But I need ID of "r" - role also, and I don't know how to add it to a checkbox on way I added Title.

Upvotes: 0

Views: 955

Answers (2)

Roxy&#39;Pro
Roxy&#39;Pro

Reputation: 4454

Because noone answered on this question for like 1 hour, I think it's ok to post answer by myself because I've found some kind of solution, I don't know is it good but it works, well for selected Check Boxes because they are acctually generated from Database (Roles) it is possible to do something like this:

private void LoadRolesToStackPanel()
{
    try
    {
        var roles = RolesController.Instance.SelectAll();
        if (roles.Count > 0)
        {
            foreach (Role r in roles)
            {
                CheckBox cb = new CheckBox();

                cb.Tag = r;

                cb.Content = r.Title.ToString();
                cb.FontSize = 15;
                stackRole.Children.Add(cb);
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

foreach (CheckBox box in selectedBoxes)
{
    Role r = (Role)box.Tag;
    //Here we get Id and every other Property that Role had
    var x = r.Id;
}

So I included .Tag property and assigned real object from DB to that tag, so I could later easily access to a properties of that DB object from my selected checkbox!

First time I see this guy "Tag" but it is awesome, and I would please anyone with bigger experience with "Tag" to explain to us why does this works like this, and how come it's so easy to access object with .Tag propery.

Upvotes: 0

mm8
mm8

Reputation: 169330

The "correct" way of solving this would be to use an ItemsControl that you bind to an IEnumerable<Role>:

<ItemsControl ItemsSource="{Binding Roles}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Title}" FontSize="15" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

public partial class MainWindow : Window
{
    private readonly ViewModel _viewModel = new ViewModel();
    public MainWindow()
    {
        InitializeComponent();
        DataContext = _viewModel;
    }
}

public class ViewModel
{
    public ViewModel()
    {
        Roles = RolesController.Instance.SelectAll();
    }

    public List<Role> Roles { get; private set; }
}

This means that you should add an IsChecked property to the Role class (or create a new client application specific Role class that has this property and use this one instead of your current Role class).

You could then iterate through the selected roles, either in the code-behind of the view or in the view model:

foreach (var role in _viewModel.Roles)
{
    if(role.IsSelected)
    {
        //...
    }
}

This solution is built on MVVM which is the recommended design pattern to use when developing XAML based user interface applications. You should learn it. You could read more about it here: https://msdn.microsoft.com/en-us/library/hh848246.aspx.

Upvotes: 1

Related Questions