Использование флажка в datagridtemplatecolumn вопросов WPF - PullRequest
1 голос
/ 04 июня 2011

Я использую технику, аналогичную http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/df77a277-91d4-41f1-a42a-0fa02a443ff4/ У меня есть встроенный в код DaataGridTemplateColumn, и я пытаюсь решить проблему с флажком «выбрать строку, затем нажмите» с сетками данных в WPF.

В общем смысле это работает, однако, если я хочу запустить событие, когда флажок установлен (т.е. CellEditEnding или RowEditEnding), кажется, что я не могу (согласно http://social.msdn.microsoft.com/Forums/en/wpf/thread/bf080945-0092-43f5-b0eb-42b2edf53dc7)

Там ДОЛЖЕНЧтобы решить эту проблему, я подумал об использовании какого-либо перенаправленного события в моем столбце шаблона при попытке вызвать событие сетки данных при нажатии флажка, но это может стать уродливым. В конечном счете, мне нужно иметь 1установите флажок и сможете запускать события сетки данных.

Помогите, пожалуйста!

Редактировать: Если я могу просто запустить RowEditEnding (каким-то образом: через барботирование или что-то еще), тогда это не будетэто не проблема ... Я просто не могу заставить его выстрелить ..

Кто-нибудь ???

Спасибо

Ответы [ 2 ]

1 голос
/ 12 октября 2011

Я столкнулся с вашим вопросом и столкнулся с тем же. Вот моя ситуация и решение, и я думаю, что оно должно работать и для вас (и других). У меня есть сетка данных, которая позволяет вводить новые элементы, поэтому возможные значения идут от 0 до бесконечности. Пользователи должны иметь возможность установить флажок и снять или снять флажок одним нажатием кнопки. Кроме того, есть и другие поля, которые также могут быть обновлены. Мне пришлось создать собственный элемент управления сеткой данных для автоматической фокусировки и начать редактирование флажка:

public class CheckboxDataGrid : DataGrid {
        public CheckboxDataGrid() {
            EventManager.RegisterClassHandler(typeof(DataGridCell),
                DataGridCell.PreviewMouseLeftButtonDownEvent,
                new RoutedEventHandler(this.OnPreviewMouseLeftButtonDown));
        }


        private void OnPreviewMouseLeftButtonDown(object sender, RoutedEventArgs e) {
            DataGridCell cell = sender as DataGridCell;
            if (cell != null && !cell.IsEditing && !cell.IsReadOnly) {

                var parentRow = cell.Parent as DataGridRow;
                if (parentRow != null) {
                    SelectedIndex = parentRow.GetIndex();
                }
                CurrentCell = new DataGridCellInfo(cell);

                DependencyObject obj = FindVisualChild<CheckBox>(cell);
                if (obj != null) {
                    BeginEdit(e);
                    System.Windows.Controls.CheckBox cb = (System.Windows.Controls.CheckBox)obj;
                    cb.Focus();
                }
            }
        }
        public static TChild FindVisualChild<TChild>(DependencyObject obj) where TChild : DependencyObject {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is TChild) {
                    return (TChild)child;
                } else {
                    TChild childOfChild = FindVisualChild<TChild>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
    }

Мне также нужен был конвертер, чтобы игнорировать новое сообщение привязки элемента из-за способа, которым WPF обрабатывает новые элементы в сетке данных:

public class IgnoreNewItemPlaceHolderConverter : IValueConverter {
        private const string NewItemPlaceholderName = "{NewItemPlaceholder}";

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            if (value != null && value.ToString() == NewItemPlaceholderName)
                return DependencyProperty.UnsetValue;
            return value;
        }

    }

Вот соответствующий XAML для сетки данных:

<chkDatagrid:CheckboxDataGrid AutoGenerateColumns="False" 
                        ItemsSource="{Binding ElementName=dgPurchaseOrders, Path=SelectedItem.Releases, NotifyOnSourceUpdated=True}" AlternatingRowBackground="#1E000000" 
                      DockPanel.Dock="Bottom" HorizontalAlignment="Left" SelectedItem="{Binding SelectedRelease, Mode=TwoWay, Converter={StaticResource ignoreNewItemPlaceHolderConverter}}"
                      MinHeight="100">
<b:Interaction.Triggers>
                            <b:EventTrigger EventName="RowEditEnding">
                                <b:InvokeCommandAction  Command="{Binding ReleaseRowEditEndingCommand}" CommandParameter="{Binding SelectedRelease}"/>
                            </b:EventTrigger>
                        </b:Interaction.Triggers>
                        <DataGrid.Columns>
                            <DataGridCheckBoxColumn Header="Is Paid" Binding="{Binding IsPaid, UpdateSourceTrigger=PropertyChanged}" />

                            <DataGridTextColumn Header="Amount" Binding="{Binding Amount,  UpdateSourceTrigger=PropertyChanged}" />
                            <DataGridTextColumn Header="Description" Binding="{Binding Description, UpdateSourceTrigger=PropertyChanged}" />
                            <DataGridTextColumn Header="Invoice Number" Binding="{Binding InvoiceNumber, UpdateSourceTrigger=PropertyChanged}" />
                            <DataGridTextColumn Header="Invoice Receive Date" Binding="{Binding InvoiceRecvDate, UpdateSourceTrigger=PropertyChanged}" />
                        </DataGrid.Columns>
                    </chkDatagrid:CheckboxDataGrid>

Вы заметите несколько вещей здесь. Я подписываюсь на событие RowEditEnding для редактирования и фиксации столбцов и применения конвертера к новой строке.

Наконец, вот код, который обновляет присоединенную сущность:

private void OnReleaseRowEditEnding(object arg) {
            if (arg != null) {
                EMService.EMEntities etx = GetEMEntities();
                EMService.Release release = (EMService.Release)arg;
                if (release.ReleaseID == 0) {
                    release.EncumbranceID = SelectedPurchaseOrder.EncumbranceID;
                    release.CreatedOn = DateTime.Now;
                    release.CreatedBy = CurrentUser.Username;
                    release.ModifiedOn = DateTime.Now;
                    release.ModifiedBy = CurrentUser.Username;
                    etx.AddObject("Releases", release);
                } else {
                    EMService.Release existingRelease = etx.Releases.Where(e => e.ReleaseID == release.ReleaseID).First();
                    existingRelease.Amount = release.Amount;
                    existingRelease.Description = release.Description;
                    existingRelease.InvoiceNumber = release.InvoiceNumber;
                    existingRelease.InvoiceRecvDate = release.InvoiceRecvDate;
                    existingRelease.IsPaid = release.IsPaid;
                    release.ModifiedOn = DateTime.Now;
                    release.ModifiedBy = CurrentUser.Username;
                    etx.UpdateObject(existingRelease);
                }
                etx.SaveChanges();
            }
        }

Это много, чтобы переварить, но в конечном итоге это сработало. Кто знал, что датагрид в WPF будет очень неприятным.

0 голосов
/ 08 июня 2011

Ответ здесь заключался в том, чтобы не обрабатывать какие-либо флажки (или попытки) в RowEditEnding.Вместо этого используйте прослушивание события PropertyChange для флажков, с которыми вы связаны, и действуйте соответствующим образом (т.е. сохраняйте изменения, когда установлена ​​привязка флажка)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...