【问题标题】:Display text instead of ID in WPF DataGrid在 WPF DataGrid 中显示文本而不是 ID
【发布时间】:2020-02-08 01:26:58
【问题描述】:

我有一个包含整数的表,这些整数是链接到另一个表的 id。例如,一个字段可能称为 StatusId,其值为 4,并查看 tblStatuses 以找到匹配的记录。

我创建了一个 WPF DataGrid 来将这些数据放入其中,一切正常。

我创建了一个 CollectionViewSource 来存储来自 tblStatuses 的记录,一切正常。

我创建了一个 CellTemplate 和 CellEditingTemplate 来显示该字段,并在编辑时显示一个带有当前状态的下拉列表,然后可以更改该下拉列表。一切正常。

我现在卡住的地方是在单元格模板的列中的查找文本值中显示当前状态,而不仅仅是 id。即显示“当前”而不是 4。

我尝试在 CellTemplate 中使用相同的 ComboBox 方法并修改 ComboBox 模板以显示标签,但它显示了错误的值。我不确定目前还可以尝试什么,而 google/so 也没有帮助,主要是因为这很难搜索。

<DataGrid Name="grdLearners" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Surname}" Header="Surname" />
            <DataGridTemplateColumn Header="Status">
               <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                     <TextBlock Text="{Binding StatusID}"></TextBlock> // displays id i.e. 4, need to display text i.e. 'Current'
                  </DataTemplate>
               </DataGridTemplateColumn.CellTemplate>
               <DataGridTemplateColumn.CellEditingTemplate>
                  <DataTemplate>
                     <ComboBox SelectedValue="{Binding StatusID}" SelectedValuePath="Status_ID" DisplayMemberPath="Status" ItemsSource="{Binding Source={StaticResource StatusesList}}"></ComboBox> // displays list of statuses and correctly shows/sets the id in the row
                  </DataTemplate>
               </DataGridTemplateColumn.CellEditingTemplate>
           </DataGridTemplateColumn>
         </DataGrid.Columns>
  </DataGrid>

希望有人能对此有所了解或为我指明正确的方向。如果您需要发布任何其他代码,请告诉我。

收集代码

<Window.Resources>
    <CollectionViewSource x:Key="StatusesList"  CollectionViewType="ListCollectionView"/>
</Window.Resources>

设置数据/集合的代码隐藏:

AppDb db = new AppDb();
var learners = db.Learners.AsNoTracking().Take(40).ToList();            

var stats = db.StudentStatuses.AsNoTracking().ToList();

CollectionViewSource itemCollectionViewSource;
itemCollectionViewSource = (CollectionViewSource)(FindResource("StatusesList"));
itemCollectionViewSource.Source = stats;

var grid = grdLearners as DataGrid;
grid.ItemsSource = learners;

【问题讨论】:

  • StatusID 属性应该如何返回string?您不会将所选字符串存储在数据对象中,您只存储 id。
  • 如果您查看 ComboBox,我在窗口上有一个 CollectionViewSource,用于存储所有状态,即 1 - 新建、2 - 待处理等。此 ComboBox 根据 StatusID 正确显示文本值财产。我想在标准单元格模板中显示匹配的文本,而不仅仅是编辑。我知道文本块不会这样做我刚刚发布了它当前如何显示 ID。我尝试在 celltemplate 中以相同的方式使用 ComboBox,但由于某种原因显示的值是错误的。
  • 你的数据对象是否实现INotifyPropertyChanged
  • 不,为了澄清,我还发布了用于在网格和集合中设置数据的代码隐藏
  • 请看我的回答。

标签: c# wpf binding datagrid


【解决方案1】:
//Simple method without complex functions if you are loading data from Database,use INNER JOINT

SELECT table1.id,....,tblStatuses.Status (if table1 has same column 'Status'then use 
"tblStatuses.Status as Stat1")
FROM table1
INNER JOIN tblStatuses
ON table1.StatusId = tblStatuses.Id;

//Directly use binding in .xaml (or Stat1 if 'as'used)
<ComboBox SelectedValue="{Binding Status}" SelectedValuePath="Status_ID" DisplayMemberPath="Status" 
                  ItemsSource="{Binding Source={StaticResource StatusesList}}"> 

【讨论】:

    【解决方案2】:

    如果要显示文本,应将其存储在数据对象中。您当前仅将 id 存储在 StatusID 属性中。如果将Status 属性添加到数据对象,则可以将CellEditingTemplateComboBoxSelectedItem 属性绑定到此:

    <TextBlock Text="{Binding Status.Status}"/>
    ...
    <ComboBox SelectedItem="{Binding Status}" DisplayMemberPath="Status" ItemsSource="{Binding Source={StaticResource StatusesList}}" />
    

    如果您不想向数据对象添加其他属性,可以使用转换器来查找 StatusesList 中的值:

    public class StatusConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int statusId = (int)values[0];
            IEnumerable<TheStatus> statuses = (IEnumerable<TheStatus>)values[1];
    
            return statuses.FirstOrDefault(x => x.Status_ID == statusId)?.Status;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    XAML:

    <DataGridTemplateColumn Header="Status">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding>
                            <MultiBinding.Converter>
                                <local:StatusConverter />
                            </MultiBinding.Converter>
                            <Binding Path="StatusID" />
                            <Binding Path="SourceCollection" Source="{StaticResource StatusesList}" />
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <ComboBox SelectedValue="{Binding StatusID}" SelectedValuePath="Status_ID" DisplayMemberPath="Status" 
                          ItemsSource="{Binding Source={StaticResource StatusesList}}"></ComboBox>
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
    

    请注意,您需要将TheStatus 更改为转换器中您的状态类型的名称。

    【讨论】:

    • 是的,我的问题是如果将文本放入对象中,则在更新下拉列表时,文本将不正确。我将尝试使用转换器,因为这可以让我直接查找文本,谢谢。
    猜你喜欢
    • 2013-03-20
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 2016-03-06
    • 2016-07-25
    相关资源
    最近更新 更多