none
Добавить новую колонку со своим binding в DataGrid: не работает суммирование RRS feed

  • Вопрос

  • Всем привет! Небольшая прелюдия.
    Подготовка:

    Создал DataGrid:

    <DataGrid Grid.Row="0" AutoGenerateColumns="True" Name="dataGrid">
            </DataGrid>

    Создал тестовый класс:

    class ABClass
            {
                public int A { get; set; }
                public int B { get; set; }
            }

    Создал коллекцию. В обработчике кнопки дополняю коллекцию новым объектом и привязываю коллекцию к dataGrid:

    ObservableCollection<ABClass> collectionsABClass = null;
            private void buttonLoad_Click(object sender, RoutedEventArgs e)
            {
                if (collectionsABClass == null)
                {
                    collectionsABClass = new ObservableCollection<ABClass>();
                }
                collectionsABClass.Add(new ABClass() { A = numberA, B = numberB });
                numberA++;
                numberB++;
                this.dataGrid.ItemsSource = collectionsABClass;
            }

    Создал еще класс:

    class TotalClass
            {
                private int total;
                public int Total 
                { 
                    get { return this.total; } 
                    set { this.total = value; } 
                }
            }

    Создал коллекцию. В обработчике кнопки дополняю коллекцию новым объектом, свойство Total которого равно сумме значений колонок A и B.

    ObservableCollection<TotalClass> collectionsTotalClass = null;
            private void buttonAddColumn_Click(object sender, RoutedEventArgs e)
            {
                if (collectionsTotalClass == null)
                {
                    collectionsTotalClass = new ObservableCollection<TotalClass>();
                }
                foreach (ABClass abItem in collectionsABClass)
                {
                    int totalAB = abItem.A + abItem.B;
                    collectionsTotalClass.Add(new TotalClass() { Total = totalAB });
                }
                DataGridTextColumn newDataGridTextColumn = new DataGridTextColumn();
                newDataGridTextColumn.Header = "Total";
     
                Binding bind = new Binding();
                bind.Source = collectionsTotalClass;
                bind.Path = new PropertyPath("Total");
     
                newDataGridTextColumn.Binding = bind;
     
                this.dataGrid.Columns.Add(newDataGridTextColumn);
            }

    Результат работы:

    A  |  B  |  Total

    0  |  0  |  0

    1  |  1  |  0

    2  |  2  |  0

    А должно быть:

    A  |  B  |  Total

    0  |  0  |  0

    1  |  1  |  2

    2  |  2  |  4

    И тут позникает проблема. В новой колонке "Total" должна отображаться эта сумма. Но этого не происходит! Подозреваю что проблема в привязке. Как это исправить!?



    • Изменено suneption 6 ноября 2012 г. 19:17
    6 ноября 2012 г. 19:15

Ответы

  • Добрый день.

    Если проблема еще актуальна, то:

    1. У вас в каждой ячейке показывается значение из первого элемента коллекции collectionsTotalClass.

    2. Данную задачу правильно решать немного по другому. Ну по крайней мере, я бы делал вот так:

    Добавил в проект вот такой вот класс:

    class SumConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int result = 0;
            ABClass item = value as ABClass;
            if (item != null)
            {
                result = item.A + item.B;
            }
            return result;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    На форме, где у вас размещен DataGrid, подключил бы пространство имен вашего приложения (4 строка), сделал бы статический ресурс асоциированный с добавленным классом (строки 6-8)  и задал бы явно столбцы, причем третий столбец, с суммой, был бы через описанный конвертер:

    <Window x:Class="WpfApplication12.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication12"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:SumConverter x:Key="SumConverter" />
        </Window.Resources>
        <Grid>
            <DataGrid Grid.Row="0" AutoGenerateColumns="False" Name="dataGrid">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="A" Binding="{Binding A}" />
                    <DataGridTextColumn Header="B" Binding="{Binding B}" />
                    <DataGridTextColumn Header="Total" Binding="{Binding Converter={StaticResource SumConverter}}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Выглядит все это теперь вот так:

    • Помечено в качестве ответа suneption 13 ноября 2012 г. 9:54
    8 ноября 2012 г. 8:53
    Отвечающий

Все ответы

  • Добрый день.

    Если проблема еще актуальна, то:

    1. У вас в каждой ячейке показывается значение из первого элемента коллекции collectionsTotalClass.

    2. Данную задачу правильно решать немного по другому. Ну по крайней мере, я бы делал вот так:

    Добавил в проект вот такой вот класс:

    class SumConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int result = 0;
            ABClass item = value as ABClass;
            if (item != null)
            {
                result = item.A + item.B;
            }
            return result;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    На форме, где у вас размещен DataGrid, подключил бы пространство имен вашего приложения (4 строка), сделал бы статический ресурс асоциированный с добавленным классом (строки 6-8)  и задал бы явно столбцы, причем третий столбец, с суммой, был бы через описанный конвертер:

    <Window x:Class="WpfApplication12.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication12"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:SumConverter x:Key="SumConverter" />
        </Window.Resources>
        <Grid>
            <DataGrid Grid.Row="0" AutoGenerateColumns="False" Name="dataGrid">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="A" Binding="{Binding A}" />
                    <DataGridTextColumn Header="B" Binding="{Binding B}" />
                    <DataGridTextColumn Header="Total" Binding="{Binding Converter={StaticResource SumConverter}}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Выглядит все это теперь вот так:

    • Помечено в качестве ответа suneption 13 ноября 2012 г. 9:54
    8 ноября 2012 г. 8:53
    Отвечающий
  • Огромное спасибо за ответ!
    13 ноября 2012 г. 10:05