Настройка элементов управления в ячейке Telerik GridView - PullRequest
1 голос
/ 29 сентября 2011

Вот конкретный пример того, что я пытаюсь сделать с помощью элемента управления Telerik GridView. Допустим, у меня есть приложение, которое будет читать файл с разделителями (скажем, CSV), который будет иметь n столбцов. Значение n может варьироваться от файла к файлу, но является постоянным внутри файла. Приложение запускается с пустой сеткой и добавляет столбцы по мере необходимости, чтобы соответствовать входному файлу. Сетка отображает все данные в виде строк во всех ячейках. Это работает либо с привязкой к BindingList, либо с помещением записи (объектов) в список GridView.Items.

Теперь я хочу поместить одну строку в верхнюю часть сетки (строку, которая не будет прокручиваться), которая содержит комбинированные списки. То есть в верхней части каждого столбца первый ряд содержит поле со списком. На первом проходе комбинированный список будет только выпадающим списком, но на следующем проходе я добавлю еще одну строку с набором комбинированных списков, которые будут доступны для редактирования. А пока давайте рассмотрим только выпадающие списки.

Конкретная проблема, с которой я сталкиваюсь, заключается в том, что я не вижу, как установить определенный тип элемента управления для конкретной ячейки. Telerik предоставляет класс GridViewComboBoxColumn, который будет определять поведение всего столбца, но это не то, что мне нужно.

Из-за переменного количества столбцов, я думаю, что код-место будет местом, где можно применить это волшебство. Возможно, мне придется что-то делать в xaml, но, поскольку я работаю в WPF всего несколько месяцев, у меня ничего не выходит.

Я сделал что-то подобное с DataGridView и XtraGrid, но это меня озадачило. Указатели будут высоко оценены.


В ответ на ответ Джонатана Д. я взял предоставленный код и изменил его, чтобы распознавать, когда редактируется ячейка в 0-й строке. В этом случае выпадающий список отображается, когда пользователь начинает операцию редактирования.

using Telerik.Windows.Controls;
using Telerik.Windows.Controls.GridView;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace LLamasoft.DataGuru.Plugin.Internal.ConfigurationUI
{
    public class RadGridViewComboboxHeaderColumn : GridViewBoundColumnBase
    {
        public static readonly DependencyProperty SelectedStringProperty =
            DependencyProperty.Register("SelectedString", typeof(string), typeof(RadGridViewComboboxHeaderColumn), new PropertyMetadata(null));

        public string SelectedString
        {
            get { return (string) GetValue(SelectedStringProperty); }
            set { SetValue(SelectedStringProperty, value); }
        }

        public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
        {
            // we need the row on which this cell lives
            GridViewDataControl gridViewDataControl = cell.ParentRow.GridViewDataControl;
            object currentEditItem = gridViewDataControl.Items.CurrentEditItem;
            int index = gridViewDataControl.Items.IndexOf(currentEditItem);

            FrameworkElement frameworkElement = null;
            if (index == 0)
            {
                BindingTarget = ComboBox.SelectedValueProperty;
                ComboBox comboBox = new ComboBox();
                // seed some values,
                // this list should be set right after construction if static, otherwise via callback if dynamic
                comboBox.Items.Add(string.Empty);
                comboBox.Items.Add("apples");
                comboBox.Items.Add("oranges");
                if (!comboBox.Items.Contains(cell.Value))
                {
                    comboBox.Items.Add(cell.Value);
                }
                comboBox.SelectedValue = SelectedString;
                frameworkElement = comboBox;
            }
            else
            {
                BindingTarget = TextBox.TextProperty;
                TextBox textBox = new TextBox();
                textBox.Text = SelectedString;
                frameworkElement = textBox;
            }

            frameworkElement.SetBinding(BindingTarget, CreateValueBinding());

            return frameworkElement;
        }

        public override object GetNewValueFromEditor(object editor)
        {
            // ensure that the control will return the correct value when queried for it
            ComboBox comboBox = editor as ComboBox;
            if (comboBox != null)
            {
                // bound to comboBox.SelectedValue which carries the correct value
            }
            TextBox textBox = editor as TextBox;
            if (textBox != null)
            {
                // bound to textBox.Text which carries the correct value
            }

            return base.GetNewValueFromEditor(editor);
        }

        private Binding CreateValueBinding()


   {
        Binding valueBinding = new Binding();
        valueBinding.Mode = BindingMode.TwoWay;
        valueBinding.NotifyOnValidationError = true;
        valueBinding.ValidatesOnExceptions = true;
        valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
        valueBinding.Path = new PropertyPath(this.DataMemberBinding.Path.Path);

        return valueBinding;
    }
}

}

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

Плохие части: 1) фиктивная запись должна быть вставлена ​​в 0-ю позицию списка и должна храниться там, 2) данные сохраняются обратно в поле в 0-й записи и могут требовать другого типа данных чем в эквивалентных полях других записей, и 3) поле со списком отображается только тогда, когда ячейка находится в режиме редактирования.

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

Еще одна проблема, с которой мне трудно поверить, это то, что я не могу легко закрепить / заморозить самые верхние ряды. Я хочу, чтобы эта строка всегда оставалась наверху после прокрутки. _Grid.Rows [0] .IsPinned = true не существует.

Telerik ответил на мой запрос о предоставлении информации и предлагает использовать селектор шаблонов, чтобы определить, как отображается ячейка. (http://www.telerik.com/community/forums/wpf/gridview/need-just-first-row-in-grid-to-be-all-comboboxes.aspx#1820310). На этом этапе я переключаю свое внимание на тестирование этого метода.

1 Ответ

0 голосов
/ 29 сентября 2011

Вы хотите создать свой собственный столбец

using System.Windows;
using System.Windows.Data;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.GridView;
using System;

namespace Inspect
{
    public class DateTimePickerColumn : GridViewBoundColumnBase
    {
        public TimeSpan TimeInterval
        {
            get
            {
                return (TimeSpan) GetValue(TimeIntervalProperty);
            }
            set
            {
                SetValue(TimeIntervalProperty, value);
            }
        }

        public static readonly DependencyProperty TimeIntervalProperty =
            DependencyProperty.Register("TimeInterval", typeof(TimeSpan), typeof(DateTimePickerColumn), new PropertyMetadata(TimeSpan.FromHours(1d)));



        public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
        {
            this.BindingTarget = RadDateTimePicker.SelectedValueProperty;

            RadDateTimePicker picker = new RadDateTimePicker();
            picker.IsTooltipEnabled = false;

            picker.TimeInterval = this.TimeInterval;

            picker.SetBinding(this.BindingTarget, this.CreateValueBinding());

            return picker;
        }

        public override object GetNewValueFromEditor(object editor)
        {
            RadDateTimePicker picker = editor as RadDateTimePicker;
            if (picker != null)
            {
                picker.DateTimeText = picker.CurrentDateTimeText;
            }

            return base.GetNewValueFromEditor(editor);
        }

        private Binding CreateValueBinding()
        {
            Binding valueBinding = new Binding();
            valueBinding.Mode = BindingMode.TwoWay;
            valueBinding.NotifyOnValidationError = true;
            valueBinding.ValidatesOnExceptions = true;
            valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
            valueBinding.Path = new PropertyPath(this.DataMemberBinding.Path.Path);

            return valueBinding;
        }
    }
}

Именно так вы создаете пользовательский столбец.Если вы измените метод CreateCellEditElement, он позволит вам создавать собственные ячейки так, как вам нравится.Вы даже должны быть в состоянии обнаружить номер строки

...