Как стилизовать WPF DataGridCell динамически - PullRequest
2 голосов
/ 01 февраля 2011

У меня есть DataGrid с itemsSource, определенным следующим образом:

dg.ItemsSource = new ObservableCollection<myRow>

...

public class myRow : Collection<myDataGridCell> { ... }

...

public interface ImyDataGridCell
{
    Brush Background { get; set; }
    Brush Foreground { get; set; }
}

, а затем яиметь классы для каждого типа столбца / ячейки:

public class myTextBoxColumn : DataGridTextColumn {...}
public class myTextBoxCell : TextBox, ImyDataGridCell {...}

, затем я устанавливаю CellStyle каждого столбца следующим образом:

в конструкторе каждого столбца:

string source = String.Format(CultureInfo.InvariantCulture, "[{0}].", dataGrid.Columns.Count);
// I set the "source" string to the column's index in the dataGrid's Columns list between [] to get an index in my binding below.

CellStyle = new Style(typeof(DataGridCell));
CellStyle.Setters.Add(new Setter(DataGridCell.BackgroundProperty, new Binding(source + "Background")));

это позволяетмне привязать фактическое свойство Background DataGridCell к свойству Background представления моей ячейки и, таким образом, изменить фон ячейки в любое время, когда я захочу.

Теперь моя главная проблема заключается в том, что этот способ работы замедляет dataGrid, какчерт ... у меня есть около 15 свойств, которые я связываю для каждой ячейки, и когда я показываю 100 столбцов х 20 строк, требуется более секунды, чтобы показать dataGrid, а затем около секунды, чтобы обновить его при горизонтальной прокрутке (мой экран можетдопускается только 20 столбцов за раз, и у меня включена виртуализация для dataGrid).

Если я избавлюсь от стиля, время отклика все равно будет больше, чем хотелось бы, но я мог бы сделать сэто.

Так есть ли лучший способ сделать это?

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

спасибо, что поделились, если у вас есть какой-либо вид / tip / предыдущий опыт по этому вопросу, яЯ хочу попробовать все, что может сделать эту чертову DataGrid быстрее ...

Редактировать: Общий эффект, которого я хочу достичь:

  • a DataGridс динамическими столбцами (количество и тип столбцов известны только во время выполнения
  • в любое время, я могу изменить любое свойство стиля отдельной ячейки: шрифт (семейство, размер, стиль, вес, оформление)если применимо), передний план, фон, textAlignment, если есть, и т.д. ...

это как раз то, чего я должен достичь.знаю, я обнаружил, что при включенной виртуализации столбцов вы не можете манипулировать REAL dataGridCells, поскольку они могут еще не отображаться (виртуализированы), и тогда вы потеряете изменение значения свойства.Итак, я пошел на этот «хак»: я связываю каждое свойство в стиле фактического dataGridCell с «логическим» и модифицирую логическое.Но это неопрятно.

Надеюсь, мне удалось объяснить себя немного лучше.

1 Ответ

1 голос
/ 01 февраля 2011

Есть ли шанс увидеть ваш медленный Ксамл? Я бы подумал, что делать это с датгергером не было бы слишком ужасно (также какую версию сетки данных вы используете в качестве .net 4.0 и версии WPF Toolkit отличаются)

Я сделал такие вещи, чтобы перекрасить выбранные предметы, и это не выглядело слишком медленно (это не правильное решение, но мне хотелось бы немного подробнее, прежде чем я скажу больше):

        <Style TargetType="DataGrid">
        <Setter Property="CellStyle">
            <Setter.Value>
                <Style TargetType="DataGridCell">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="{StaticResource SelectedBackgroundBrush}" />
                            <Setter Property="BorderBrush" Value="{x:Null}" />
                            <Setter Property="Foreground" Value="White" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>
...