Enhancing the display of a particular column in a WPF grid view

c#, wpf, wpfdatagrid

Solution

Here is a short piece of code I've whipped up to get you started. I've assumed that you can hydrate `IsMember` property of `Role` class when you create the application user. I've taken the easiest route by having all roles in all users (`enum flags` would have been best but given your data, I'm not sure that's an option without some plumbing). I've used minimal columns to get the idea across. If you implement `INotifyPropertyChanged` on Roles at least, you can hook up to the notification and persist it back into database when the check-boxes change on front end.

Main Xaml

<DataGrid DataContext="{StaticResource ResourceKey=AllUsers}" ItemsSource="{Binding}" AutoGenerateColumns="False">
        <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding GivenName}" />
        <DataGridTextColumn Binding="{Binding Surname}" />
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding ApplicationRoles}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <CheckBox Content="{Binding RoleName}" IsChecked="{Binding IsMember, Mode=TwoWay}" />
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Data Xaml

<x:Array x:Key="AllUsers" Type="Sample:ApplicationUser">
    <Sample:ApplicationUser GivenName="Andrew" Surname="Fuller">
        <Sample:ApplicationUser.ApplicationRoles>
            <Sample:Role RoleName="Administrators" IsMember="True"/>
            <Sample:Role RoleName="Shift Analysts"/>
            <Sample:Role RoleName="Shift Managers" IsMember="True"/>
        </Sample:ApplicationUser.ApplicationRoles>
    </Sample:ApplicationUser>
    <Sample:ApplicationUser GivenName="Anne" Surname="Dodsworth">
        <Sample:ApplicationUser.ApplicationRoles>
            <Sample:Role RoleName="Administrators"/>
            <Sample:Role RoleName="Shift Analysts" IsMember="True"/>
            <Sample:Role RoleName="Shift Managers" IsMember="True"/>
        </Sample:ApplicationUser.ApplicationRoles>
    </Sample:ApplicationUser>
</x:Array>

Class definitions

public class ApplicationUser
{
    public Guid? UserId { get; set; }
    public string GivenName { get; set; }
    public string Surname { get; set; }
    public string EmailAddress { get; set; }
    public string UserPhone { get; set; }
    public string NtLoginName { get; set; }
    public List<Role> ApplicationRoles { get; set; }

    public ApplicationUser()
    {
        ApplicationRoles = new List<Role>();
    }
}

public class Role
{
    public Guid RoleId { get; set; }
    public string RoleName { get; set; }
    public string RoleDescription { get; set; }

    public bool IsMember { get; set; }
}

Result

Problem

I have some user admin functionality in a WPF app that I'm currently writing and would like to make it a bit more intuitive for the end user I'd like to be able to provide some kind of means of easily editing the list of roles a given user belongs to. At the moment the grid is filled as a result of binding to a `List<ApplicationUser>` `ApplicationUser` is my own class defined as: ``` public class ApplicationUser { public Guid? UserId { get; set; } public string GivenName { get; set; } public string Surname { get; set; } public string EmailAddress { get; set; } public string UserPhone { get; set; } public string NtLoginName { get; set; } public List<Role> ApplicationRoles { get; set; } } ``` As can be seen the roles that the user is in are held in a `List<Role>`. `Role` is my own class defined as: ``` public class Role { public Guid RoleId; public string RoleName; public string RoleDescription; } ``` The below mockup represents the current state where I just get the roles as a List and through the use of a converter just display the roles as new-line separated strings in the gridview However this is what I'd like to achieve to make toggling off and on membership of various groups easier. Now that I think about it I'll probably have to change the definition of Role to include an IsMember property to facilitate binding on the checkbox but if anybody has a better way I'll welcome that as well. I can change the JOIN type in the sproc so I get back all roles with a query about a particular user and fill the IsMember property accordingly. Thanks for your time!

Original source