WinUI3 Datagrid TemplatedColumn с всплывающей кнопкой

Я разрабатываю приложение WinUI3. Я хотел бы иметь сетку данных CommunityToolkit со столбцом кнопки в каждой строке. При нажатии кнопки должно появиться всплывающее окно, позволяющее пользователю вводить данные для заполнения этого поля.

Для простоты я поместил в пример только две кнопки, но приложению потребуется больше элементов управления:

<controls:DataGridTemplateColumn Header = "Value" IsReadOnly = "True">
    <controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid>
                <Button Content = "{Binding Value}" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch">
                    <Button.Flyout>
                        <Flyout>
                            <StackPanel>
                                <TextBlock Text = "All items will be removed. Do you want to continue?" Margin = "0,0,0,12" />
                                <Button Content = "Yes, empty my cart" Click = "Button_Click" />
                                <Button Content = "No, cart is full" Click = "FullButton_Click" />
                            </StackPanel>
                        </Flyout>
                    </Button.Flyout>
                </Button>
            </Grid>
        </DataTemplate>
    </controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>

Гифка

Как показано на гифке, у меня проблемы с фокусировкой при нажатии. Первый щелчок работает как чудо, дальнейшее нажатие, похоже, переводит ячейку в режим редактирования, и всплывающее окно не запускается. Если я изменю фокус на другие строки/ячейки, результаты каждый раз будут разными.

Я думаю, что существует механизм редактирования/пропуска кликов, которого я не знаю, как избежать. Перевод ячейки в режим «IsReadOnly» не меняет поведение.

Если я попытаюсь использовать MenuFlyout или ContextFlyout в ячейке, это работает отлично, но мне нужно показать больше элементов управления, а не простое меню, которое будет запускаться при щелчке правой кнопкой мыши.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Раньше у DataGridComboBoxColumn была такая же проблема , и вы можете увидеть здесь, как она была исправлена.

Вы можете создать собственные DataGrid и Column и применить аналогичное исправление следующим образом:

ОБНОВЛЯТЬ

Я обновил свой ответ таким образом, чтобы вы могли отменить режим редактирования явно, когда Flyout закрыт.

public class DataGridButtonWithFlyoutColumn : DataGridTemplateColumn
{
    public event EventHandler<object>? FlyoutClosed;

    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        if (editingElement is Button button)
        {
            button.Flyout.ShowAt(button);
            button.Flyout.Closed += (s, e) =>
            {
                this.FlyoutClosed?.Invoke(this, e);
            };
        }

        return base.PrepareCellForEdit(editingElement, editingEventArgs);
    }
}
public class DataGridEx : DataGrid
{
    public DataGridEx()
    {
        this.BeginningEdit += DataGridEx_BeginningEdit;
    }

    private void DataGridEx_BeginningEdit(object? sender, DataGridBeginningEditEventArgs e)
    {
        if (e.Column is DataGridButtonWithFlyoutColumn column)
        {
            column.FlyoutClosed += DataGridButtonWithFlyoutColumn_FlyoutClosed;
        }
    }

    private void DataGridButtonWithFlyoutColumn_FlyoutClosed(object? sender, object e)
    {
        _ = CancelEdit();

        if (sender is DataGridButtonWithFlyoutColumn column)
        {
            column.FlyoutClosed -= DataGridButtonWithFlyoutColumn_FlyoutClosed;
        }
    }
}

и используйте его следующим образом:

<local:DataGridEx
    x:Name = "DataGridControl"
    ItemsSource = "{x:Bind Items}">
    <toolkit:DataGrid.Columns>
        <toolkit:DataGridTextColumn
            Binding = "{Binding Name}"
            Header = "Name" />
        <toolkit:DataGridComboBoxColumn
            Binding = "{Binding Type}"
            Header = "Type"
            ItemsSource = "{x:Bind Types, Mode=OneWay}" />
        <local:DataGridButtonWithFlyoutColumn Header = "Value">
            <local:DataGridButtonWithFlyoutColumn.CellTemplate>
                <DataTemplate>
                    <Grid Background = "LightGreen">
                        <TextBlock
                            HorizontalAlignment = "Stretch"
                            VerticalAlignment = "Center"
                            HorizontalTextAlignment = "Center"
                            Text = "{Binding Value}" />
                    </Grid>

                </DataTemplate>
            </local:DataGridButtonWithFlyoutColumn.CellTemplate>
            <toolkit:DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <Button
                        HorizontalAlignment = "Stretch"
                        VerticalAlignment = "Stretch"
                        Background = "HotPink"
                        Content = "{Binding Value}"
                        FontWeight = "ExtraBold">
                        <Button.Flyout>
                            <Flyout>
                                <StackPanel>
                                    <TextBlock
                                        Margin = "0,0,0,12"
                                        Text = "All items will be removed. Do you want to continue?" />
                                    <Button
                                        Click = "Button_Click"
                                        Content = "Yes, empty my cart" />
                                    <Button
                                        Click = "Button_Click_1"
                                        Content = "No, cart is full" />
                                </StackPanel>
                            </Flyout>
                        </Button.Flyout>
                    </Button>
                </DataTemplate>
            </toolkit:DataGridTemplateColumn.CellEditingTemplate>
        </local:DataGridButtonWithFlyoutColumn>
    </toolkit:DataGrid.Columns>
</local:DataGridEx>

Большое спасибо, таким образом всплывающее окно появляется каждый раз, когда ячейка переходит в режим редактирования. К сожалению, если ячейка уже находится в режиме редактирования, постоянное нажатие вызывает ту же проблему. Кнопка «Мне нравится» не запускает всплывающее окно. Я попробовал зарегистрироваться на событие клика и сделал Flyout.ShowAt, но безуспешно.

fasigno 09.04.2024 16:41

Ты прав. Я обновил свой ответ таким образом, чтобы вы могли отменить режим редактирования явно, когда Flyout закрыт.

Andrew KeepCoding 10.04.2024 04:13

Еще раз спасибо за обновление вашего ответа. Работает хорошо. Я считаю довольно глупой необходимость переопределять DataGrid только для того, чтобы кнопка работала. Я имею в виду, что я нахожусь в режиме редактирования, кнопка создана и находится сверху, и она должна получать клики.

fasigno 12.04.2024 15:19

Другие вопросы по теме