Как использовать DisplayMemberPath в WPF CellTemplate? - PullRequest
0 голосов
/ 03 мая 2020

В DataGrid одним из столбцов является Учетная запись. Я хочу выбрать AccountId, но ComboBox должен отображать AccountNames. Итак, я создал XAML ниже. Он работает как требуется, но у него есть недостаток. Если я изменю учетную запись и go на другую ячейку в той же строке, то AccountName еще не обновляется. (Если я покидаю строку, то AccountName вычисляется и обновляется на основе нового AccountId.)

Если я использую только CellTemplate с ComboBox, тогда я избежал проблемы, но мне не нравится это решение, потому что оно не очень хорошее показывать комбинированные списки, когда они не нужны. Я мог бы попытаться обновить AccountName, когда я покину ячейку, но мое представление БД сделало бы это, и в этот момент могли быть ошибки в текущей строке. Поэтому я хотел бы показать выбранное AccountName как TextBlock в CellTemplate на основе AccountId. (Я попытался поместить ComboBox в TextBlock, но тогда TextBlock показывает не только выбранное имя учетной записи, но и сам ComboBox.)

<DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding AccountName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" 
                       Style="{StaticResource TextBlockError}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
                AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}" 
                      SelectedValue="{Binding AccountId, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" 
                      SelectedValuePath="Id"
                      DisplayMemberPath="Name"
                      Style="{StaticResource ComboBoxError}" IsEditable="True"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Вам следует привязать свойство Account вашего объекта данных и реализовать интерфейс INotifyPropertyChanged . Вы также можете установить для свойства UpdateSourceTrigger значение PropertyChanged:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
            AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}" 
          SelectedItem="{Binding Account, UpdateSourceTrigger=PropertyChanged}" 
          DisplayMemberPath="Name"
          Style="{StaticResource ComboBoxError}" IsEditable="True"/>
0 голосов
/ 11 мая 2020
  • Мне очень помог ответ @ mm8.
  • До сих пор в моем файле модели был только int AccountId.
  • Я ввел свойство навигации по учетной записи, которое создало внешний ключ в БД.
    • (я использую Enitity Framework.)
  • При обновлении базы данных учетная запись не изменяется только AccountId.
    • (В противном случае возникают проблемы с базой данных, EF считает, что вместо новой учетной записи следует добавить новую учетную запись.)
  • Теперь также можно установить свойство учетной записи. изменяет AccountId.
  • Учетная запись реализует IEquatable
    • , в противном случае начальное значение ComboBox не отображается
  • Наконец, xaml (SelectedItem = "{Binding Account } "and Text =" {Binding Account.Name} "используется)

            <DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Account.Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" 
                                   Style="{StaticResource TextBlockError}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
                            AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}" 
                                  SelectedItem="{Binding Account, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" 
                                                                        DisplayMemberPath="Name"
                                  Style="{StaticResource ComboBoxError}" IsEditable="True"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
                <DataGridTemplateColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <TextBlock Text ="{Binding Account.Name}" TextWrapping="Wrap" MaxWidth="300"/>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGridTemplateColumn.CellStyle>
            </DataGridTemplateColumn>
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...