WPF How to display relational data in DataGrid's TextBlock like in ComboBox

白昼怎懂夜的黑 提交于 2021-02-11 12:32:13

问题


When searching for help on this topic, I typically find information on how to populate a ComboBox with related data (display name in one table for the foreign key in originating table), but I am already able to do that. I am looking for a solution on how to achieve the same result in a TextBlock.

In my project I have created a link to an SQL database using EntityFramework. There are two tables: Personnel and Role. They are related with Personnel.RoleIdFk and Role.RoleId.

I am able to get a combobox to display the Role.RoleName for the associated RoleIdFk.

In my ViewModel:

    private ICollection<Role> roleList;
    public ICollection<Role> RoleList
    {
        get { return roleList; }
        set { roleList = value; NotifyPropertyChanged("RoleList"); }
    }

    private Role selectedRole;
    public Role SelectedRole
    {
        get { return selectedRole; }
        set { selectedRole = value; NotifyPropertyChanged("SelectedRole"); }
    }

    public void SetSelectedRole()
    {
        if (SelectedPerson == null)
        {
            SelectedPerson = PersonnelList.Select(p => p)
                                          .FirstOrDefault();
        }


        SelectedRole = RoleList.Where(p => p.RoleId == SelectedPerson.RoleIdFk)
                                   .FirstOrDefault();
    }

And the XAML for the ComboBox:

        <ComboBox x:Name="cboRole"
              Grid.Column="1" Grid.Row="0"
              Width="150" Height="35"
              ItemsSource="{Binding RoleList}"
              DisplayMemberPath="RoleName"
              SelectedItem="{Binding SelectedRole}"
              />

My problem is I am also displaying a DataGrid for the Personnel table. In this DataGrid, I would like to have the associated RoleName displayed instead of the numerical foreign key.
The current XAML for the DataGrid:

<Window.DataContext>
    <viewModel:MainWindowVM />
</Window.DataContext>

    <ListView Name="lstPersonnel"
              Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"
              ItemContainerStyle="{StaticResource ItemContStyle}"
              ItemsSource="{Binding PersonnelList}" >
        <ListView.View>
            <GridView>
                <GridViewColumn Width="75" Header="First Name" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding FirstName}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

                <GridViewColumn Width="75" Header="Last Name" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding LastName}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

                <GridViewColumn Width="75" Header="Role" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding RoleIdFk}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

This is what the grid looks like:

For the final column, I have tried altering the text field in various ways. I have also tried using other Templates and Styles. None of these have been successful.

Is there a way to actually perform this in XAML itself, or am I going to have to set up some sort of value converter to accomplish this?

NOTE: I had thought of using some sort of "switch/case" scenario. While it would work here, I need to figure out something that can be more dynamic. Later in the project I will need to associate the PersonnelId with other items. A "switch/case" scenario is not feasible with 300+ people.


回答1:


"Role" should be available in "Personnel" object. So you can simply use "Role.RoleName" instead of "RoleIdFk":

<TextBlock Text="{Binding Role.RoleName}" />

In cases when you don't have a referenced object, it's better to join two collections and use a result as an ItemsSource of a DataGrid. Here is an example: Joining two tables in one datagrid usig Linq C# WPF

There is also a solution with IMultiValueConverter, but it seems overcomplicated: Joining 2 collections into datagrid using multibinding



来源:https://stackoverflow.com/questions/39538676/wpf-how-to-display-relational-data-in-datagrids-textblock-like-in-combobox

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!