none
DataGrid как заставить C# понимать название Grida RRS feed

  • Вопрос

  • LinesDom =

         

    new ObservableCollection<LineDom>();
    биндинг с DataGrid сделан в LinesDom.  Я хочу обраться к свойствам DataGrid и менять цвет ячеек или столбцов во время вывода данных. Как мне заставить C# распознать DataGrid и выполнить изменение свойств цвета фона 
    26 октября 2012 г. 13:29

Ответы

  • Вы немного не понимаете как работает XAML. Но раз вы считаете, что подход с редактированием цвета ячеек из кода проще, пусть. Вот вам пример. Пусть есть форма с вот такой разметкой:

    <Window x:Class="WpfApplication19.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" >
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="1*" />
            </Grid.RowDefinitions>
            <Button Content="Раскрасить" Click="Button_Click"></Button>
            <DataGrid x:Name="dgMain" Grid.Row="1" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding [0]}" />
                    <DataGridTextColumn Binding="{Binding [1]}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Ну и можно для нее дописаь вот такой вот код в cs файле:

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Random rnd = new Random();
                int[][] numbers = new int[10][];
                for (int i = 0; i < 10; i++)
                {
                    numbers[i] = new int[] { rnd.Next(3), rnd.Next(3) };
                }
                dgMain.ItemsSource = numbers;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {        
                
                for (int i = 0; i < dgMain.Items.Count; i++)
                {   
                    DataGridRow row = (dgMain.ItemContainerGenerator.ContainerFromIndex(i)) as DataGridRow;
                    var border = VisualTreeHelper.GetChild(row, 0);
                    var selectiveScrollingGrid = VisualTreeHelper.GetChild(border, 0);
                    var dataGridCellsPresenter = VisualTreeHelper.GetChild(selectiveScrollingGrid, 0);
                    var itemsPresenter = VisualTreeHelper.GetChild(dataGridCellsPresenter, 0);
                    DataGridCellsPanel dataGridCellsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as DataGridCellsPanel;
                    DataGridCell cell = dataGridCellsPanel.Children[1] as DataGridCell; // Вот здесь 1 - это индекс столбца (нумерация с нуля)
                    int[] data = row.Item as int[]; // Извлекаем набор данных связанных со строкой в DataGrid
                    if (data[1] == 0)
                    {
                        cell.Background = new SolidColorBrush(Colors.Red);
                    }
                }
            }
        }

    После запуска приложения, DataGrid заполняется данными:

    После нажатия на кнопку, ячейки во втором столюце содержащие ноль закрашиваются красным:

    Как видите, работает именно так, как вы и хотели... но если вы считаете что это решение проще, чем разобраться как правильно, воля ваша.

    • Помечено в качестве ответа Abolmasov Dmitry 13 ноября 2012 г. 8:42
    26 октября 2012 г. 16:38
    Отвечающий

Все ответы

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

    Не пложите ветки с одним и тем же вопросом. Вот в этой ветке я вам ответил.

    26 октября 2012 г. 13:47
    Отвечающий
  • Ну для того, чтобы получить доступ к визуальным элементам им можно присваивать имена. Например вот так:

    <DataGrid x:Name="dgMain" />

    ну и тогда из cs файла этого окна можно будет обращаться:

    dgMain.ItemsSource
    P.s. Но, на будущее, лучше разберитесь с Binding, патерном MVVM, XAML-ом. Тогда вы будите решать стоящие перед вами задачи на много быстрее и использовать именно те средства, которые задумывались при разработке на WPF...
    26 октября 2012 г. 14:39
    Отвечающий
  • Нашел имя Грида: в xaml

    <Grid x:Name="grdDataDom" />

     и само имя в C# определяется.

    Но вот запись grdDataDom.ItemsSource

    и grdDataDom.Row(1)

    не понимает, в выпадающем списке ItemsSource  нет.

    И как обратиться к свойству бэкграунт строки или ячейки?

     Книжки по Бленду и WPF уже заказаны.))


    26 октября 2012 г. 15:18
  • Коллега, а вас не смущает, что мы обсуждаем DataGrid, а вы нашли имя элемента Grid?

    Ну а по поводу фона, здесь все сложно... Если в WinForms приложениях вы были вынуждены в списки передавать элементы того типа, который поддерживал список, то в WPF, вы передаете любые элементы и для них создается представление по умолчанию, или вы можете задать свое представление... Так вот, поменять фон у ячеек грида, вам скорее всего придется именно через конвертор или воспользоваться паттерном обертка (он же адаптер), для того, чтобы у каждого элемента описывающего строку был цвет. Но и в этом случае вам придется из XAML добавить к нему Binding...

    26 октября 2012 г. 15:24
    Отвечающий
  • Я же у строк поменял цвет через DataGrid_LoadingRow, значит также можно и у Cell.

    Мне мой способ понравился вот и ещу такой же метод для ячеек. Вариант с WPF сильно длинный.

    Мне придется задавать доп стили для каждого столбца, создавать конвертеры для каждого столбца. А если еще несколько цветов по условию?

     Я со строками сделал очень удобно для моих целей. Через e.Row. BackGround(Colors.White)

    26 октября 2012 г. 15:40
  • Вы немного не понимаете как работает XAML. Но раз вы считаете, что подход с редактированием цвета ячеек из кода проще, пусть. Вот вам пример. Пусть есть форма с вот такой разметкой:

    <Window x:Class="WpfApplication19.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" >
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="1*" />
            </Grid.RowDefinitions>
            <Button Content="Раскрасить" Click="Button_Click"></Button>
            <DataGrid x:Name="dgMain" Grid.Row="1" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding [0]}" />
                    <DataGridTextColumn Binding="{Binding [1]}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Ну и можно для нее дописаь вот такой вот код в cs файле:

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Random rnd = new Random();
                int[][] numbers = new int[10][];
                for (int i = 0; i < 10; i++)
                {
                    numbers[i] = new int[] { rnd.Next(3), rnd.Next(3) };
                }
                dgMain.ItemsSource = numbers;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {        
                
                for (int i = 0; i < dgMain.Items.Count; i++)
                {   
                    DataGridRow row = (dgMain.ItemContainerGenerator.ContainerFromIndex(i)) as DataGridRow;
                    var border = VisualTreeHelper.GetChild(row, 0);
                    var selectiveScrollingGrid = VisualTreeHelper.GetChild(border, 0);
                    var dataGridCellsPresenter = VisualTreeHelper.GetChild(selectiveScrollingGrid, 0);
                    var itemsPresenter = VisualTreeHelper.GetChild(dataGridCellsPresenter, 0);
                    DataGridCellsPanel dataGridCellsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as DataGridCellsPanel;
                    DataGridCell cell = dataGridCellsPanel.Children[1] as DataGridCell; // Вот здесь 1 - это индекс столбца (нумерация с нуля)
                    int[] data = row.Item as int[]; // Извлекаем набор данных связанных со строкой в DataGrid
                    if (data[1] == 0)
                    {
                        cell.Background = new SolidColorBrush(Colors.Red);
                    }
                }
            }
        }

    После запуска приложения, DataGrid заполняется данными:

    После нажатия на кнопку, ячейки во втором столюце содержащие ноль закрашиваются красным:

    Как видите, работает именно так, как вы и хотели... но если вы считаете что это решение проще, чем разобраться как правильно, воля ваша.

    • Помечено в качестве ответа Abolmasov Dmitry 13 ноября 2012 г. 8:42
    26 октября 2012 г. 16:38
    Отвечающий
  • Мне пока с dgMain вообще не удается ничего сделать.

    У меня DataGrid прекрасно заполяется, новые строки онлайн поступают т е нулевая строка постоянно меняется или через изменение или через вставку. Мне бы только при выводе свойство ячейки поменять.

    Нужен обработчик событий, который бы мне позволил со свойствами ячеек нулевой строки поработать. Чтобы было обращение rows[0].cells[5] или просто текущей строки cells[5], мне не требуются другие строки для выбора.



    26 октября 2012 г. 17:15
  • Привет.

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


    Для связи [mail]

    13 ноября 2012 г. 8:40