DataGridTemplateColumn.CellEditingTemplate преобразование TextBox в Combobox несовместимо - PullRequest
1 голос
/ 05 августа 2020

У меня есть следующий код XAML:

<DataGrid ItemsSource="{Binding TempParameters}" AutoGenerateColumns="False" CanUserAddRows="False" Height="100" Name="TempParameterGrid" CanUserSortColumns="False" Width="{Binding Source={StaticResource theWidth}}" MouseDown="SetSelectedGrid">
     <DataGrid.Columns>
         <DataGridTextColumn Width="*" Header="ID"  IsReadOnly="True" Binding="{Binding ID}"/>
         <DataGridTemplateColumn Header="Parameter" IsReadOnly="False" >
             <DataGridTemplateColumn.CellEditingTemplate>
                 <DataTemplate>
                     <ComboBox SelectedValue="{Binding name, Mode=TwoWay}" ItemsSource ="{Binding ParameterNames, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                 </DataTemplate>
             </DataGridTemplateColumn.CellEditingTemplate>
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <TextBox Text ="{Binding name, Mode=TwoWay}" />
                 </DataTemplate>
             </DataGridTemplateColumn.CellTemplate> 
         </DataGridTemplateColumn>
         <DataGridTextColumn Width="*" Header="Start"      IsReadOnly="False" Binding="{Binding start}"/>
         <DataGridTextColumn Width="*" Header="End"        IsReadOnly="False" Binding="{Binding end}"/>
         <DataGridTextColumn Width="*" Header="Samples"    IsReadOnly="False" Binding="{Binding samples}"/>
     </DataGrid.Columns>
 </DataGrid>

DataGrid привязывается к свойству коллекции TempParameters. Это набор следующих объектов:

    public class TuneParameterRecord {
        public int ID { get; set; }
        public string name { get; set; }
        public double start { get; set; }
        public double end { get; set; }
        public int samples { get; set; }
    }

Все столбцы доступны для редактирования. Однако мне нужно, чтобы в столбце имени был список предопределенных имен. Поэтому я подумал предоставить ComboBox список допустимых значений (хотя многие укажут на это, этот список не может быть перечислением. Мне нужно, чтобы это был список строк). Этот список предоставляется в контексте данных окна.

Я могу ссылаться на него напрямую, предоставляя относительный источник в CellEditingTemplate. Моя проблема в том, что когда я пытаюсь отредактировать ячейку в соответствующем столбце, я получаю курсор, который может редактировать текстовое поле вместо получения поля со списком.

Чтобы получить поле со списком. Мне нужно несколько раз щелкнуть мышью в области, обозначенной красным на прикрепленных изображениях. Первое изображение показывает, что ячейка редактируется с помощью курсора, а второе изображение имеет поле со списком (хотя и замаскировано) после того, как я несколько раз щелкнул в указанной красной области.

Cursor Editing at a place where a combobox was supposed to be Красная область, в которой я нажимаю несколько раз, чтобы появилось поле со списком

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Итак, я нашел проблему. Я преобразовал

<DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
         <TextBox Text ="{Binding name, Mode=TwoWay}" />
     </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

в

<DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
         <TextBlock Text ="{Binding name, Mode=TwoWay}" />
     </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

Это значение по умолчанию для желаемого поведения. У меня такое чувство, что я получил непоследовательное поведение, потому что TextBox можно редактировать, а Textblock - нельзя. Таким образом, одним щелчком мыши можно выбрать TextBox, но не вернуться к шаблону редактирования ячейки.

0 голосов
/ 05 августа 2020

У меня по сути тот же XAML, который вы разместили в моем коде. Однако мой XAML также включает в себя следующее как часть поля со списком:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <helpers:TakeFocusAction />
    </i:EventTrigger>
</i:Interaction.Triggers>

Его цель - поместить фокус в поле со списком всякий раз, когда появляется CellEditingTemplate.

TakeFocus действие выглядит так:

using System.Windows;
using System.Windows.Interactivity;

namespace Helpers
{
    public class TakeFocusAction : TriggerAction<UIElement>
    {
        protected override void Invoke(object parameter)
        {
            AssociatedObject.Focus();
        }
    }
}

Вам понадобятся следующие пространства имен в вашем Xaml:

xmlns:helpers="clr-namespace:Helpers"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

Если у вас его еще нет, вам понадобится пакет Nuget Microsoft.Xaml.Behaviors.Wpf , который предоставляет пространство имен интерактивности, указанное выше.

...