Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > WPF DataGrid календарь


Автор: xTr1m 6.4.2012, 08:18
День добрый, есть у меня DataGrid (работаю в Expression Blend), его колонки должны представлять из себя дни текущего месяца. Месяца естественно меняются. Я не могу понять как организовать это через binding. Допустим, что я связываю колонки с каким то списком, который представляет собой дни месяца. А как тогда связать эти колонки с данными, которые будут представлять строки? В общем какая то каша в голове, наверное я чего то недопонимаю.

Автор: erm0l0v 6.4.2012, 08:43
Я реализовывал подобную функциональность, к сожалению мое решение недостаточно расширяемое по этому вам придется заточить его под свою задачу.

И так во первых для того чтобы реализовать произвольное количество колонок вам нужно писать код. Я реализовал это с помощью Behavior, и я реализовывал эту задачу на Silverlight думаю что для WPF этот Behavior будет отличаться несильно.

Вот код моего Behavior
Код

public class LineF130View : Behavior<DataGrid>
    {
        public static readonly DependencyProperty CellStyleDataGridTextColumnProperty = DependencyProperty.Register("CellStyleDataGridTextColumn", typeof(Style), typeof(LineF130View), new PropertyMetadata(null));

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(AssociatedObject_AutoGeneratingColumn);
        }

        public Style CellStyleDataGridTextColumn { get; set; }

        void AssociatedObject_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            if (e.PropertyName == "OPSName")
            {
                AssociatedObject.Columns.Clear();
                AssociatedObject.Columns.Add(
                    new DataGridTextColumn
                    {
                        Header = "Отделение",
                        Binding = new Binding("OPSName"),
                    }
                    );
                var elems = (IEnumerable<LineF130FromDataGrid>)AssociatedObject.ItemsSource;
                var dates = elems.SelectMany(el => el.Sums.Keys).Distinct();
                foreach (var d in dates)
                {
                    AssociatedObject.Columns.Add(
                        new DataGridTextColumn
                        {
                            Header = d.ToShortDateString(),
                            Binding = new Binding("[" + d.ToShortDateString() + "]") { StringFormat = "{0:c}" },
                            CellStyle = CellStyleDataGridTextColumn,
                        });
                }


                e.Cancel = true;
            }
            else
            {
                e.Cancel = false;
            }
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.AutoGeneratingColumn -= new EventHandler<DataGridAutoGeneratingColumnEventArgs>(AssociatedObject_AutoGeneratingColumn);
        }
    }


здесь мы вешаемся на событие AutoGeneratingColumn и навязываем ему свою логику.

а биндинг у меня осуществлялся к коллекции таких классов:
Код

public class LineF130FromDataGrid
    {
        public LineF130FromDataGrid(Dictionary<DateTime, decimal> Sums)
        {
            this.Sums = Sums;
        }

        public string OPSName { get; set; }

        public Dictionary<DateTime, decimal> Sums;

        [Display(AutoGenerateField = false)]
        public decimal this[string date]
        {
            get
            {
                if (Sums.ContainsKey(Convert.ToDateTime(date)))
                    return Sums[Convert.ToDateTime(date)];
                else
                    return 0;
            }
        }
    }


Как я уже говорил решение получилось не очень изящное и совсем не гибкое но меня вполне устроило.

Автор: xTr1m 6.4.2012, 09:00
Спасибо, оказывается я много чего не знаю =)) буду разбираться. Единственное, глядя, на все это задаюсь вопросом. А не легче ли тогда полностью самому из кода контролировать содержимое таблицы. Ну то есть без bindinga?

Автор: erm0l0v 6.4.2012, 09:25
Как сказать, вопрос сложный. В больших проектах Binding себя оправдывает в маленьких может показаться стрельбой из пушки по воробьям.

Но в любом случае при использовании Expression Blend я бы вам рекомендовал использовать Binding, удобно когда все данные загружены в форму еще в дизайнере.

Лично мне нравится использовать Binding я уже привык к нему и на все остальное смотрю как на что то из каменного века.

А задача озвученная в вашем посте подразумевает написание кода, это может быть добавление кода в xaml.cs или переопределение DataGrid но я посчитал что более правильно будет использовать Behavior.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)