DXGrid меняет цвет сетки ряда DevExpress WPF
У меня есть юридическое лицо IsRemoved
, Когда это станет правдой, сетка должна стать серой.
Для этого я использую этот код:
<dxg:TableView.RowStyle>
<Style TargetType="{x:Type dxg:GridRowContent}">
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.IsRemoved, Mode=OneWay}" Value="True">
<Setter Property="Background" Value="Gray" />
</DataTrigger>
</Style.Triggers>
</Style>
</dxg:TableView.RowStyle>
</dxg:TableView>
Но он будет работать только тогда, когда сетка показывает в первый раз. Я хочу изменить цвет, когда значение меняется. Недвижимость реализует INotifyPropertyChange
Событие.
3 ответа
Примечание: этот ответ является устаревшим (см. Мой другой ответ).
Этот ответ предназначен для версий DevExpress до v14.1 или DevExpress версии 14.1 и после с
UseLightweightTemplates="None"
,
Вам нужно иметь начальный установщик для свойства, которое вы хотите изменить. Это связано с порядком, в котором WPF использует стили.
Добавьте эту строку после тега стиля:
<Setter Property="Background" Value="Black" />
Полный пример:
<dxg:TableView.RowStyle>
<Style TargetType="{x:Type dxg:GridRowContent}">
<Setter Property="Background" Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.IsRemoved, Mode=OneWay}" Value="True">
<Setter Property="Background" Value="Gray" />
</DataTrigger>
</Style.Triggers>
</Style>
</dxg:TableView.RowStyle>
Начиная с версии 14.1 DevExpress, они представили Оптимизированный режим, который использует облегченные шаблоны. Это делает все быстрее, но требует изменения того, как указаны стили и DataTriggers.
Легкие шаблоны контролируются прикрепленным свойством UseLightweightTemplates="Row"
, который включен по умолчанию. Можно переключить на None
для обратной совместимости.
Вот рабочий пример MVVM, как покрасить строку, если IsDirty
свойство устанавливается для любой строки сетки.
<dxg:GridControl x:Name="MyGridControl"
ItemsSource ="{Binding MyViewModelList}"
SelectionMode="None"
VerticalAlignment="Stretch">
<dxg:GridControl.Resources>
<SolidColorBrush x:Key="GridRowIsDirty" Color="#FF602D2D" />
</dxg:GridControl.Resources>
<dxg:GridControl.View>
<dxg:TableView UseLightweightTemplates="Row" >
<dxg:TableView.RowStyle>
<Style TargetType="dxg:RowControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Row.IsDirty}" Value="True">
<Setter Property="Background" Value="{StaticResource GridRowIsDirty}" />
</DataTrigger>
</Style.Triggers>
</Style>
</dxg:TableView.RowStyle>
</dxg:TableView>
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn x:Name="Included" FieldName="Included"/>
<dxg:GridColumn x:Name="ColumnB" Header="Column B" FieldName="ColumnB" ReadOnly="True"/>
<dxg:GridColumn x:Name="ColumnC" Header="Column C" FieldName="ColumnC" ReadOnly="True"/>ReadOnly="True"/>
</dxg:GridControl.Columns>
</dxg:GridControl>
В ViewModel за этой сеткой:
public ObservableCollection<MyViewModel> MyViewModelList { get; set; }
Каждая строка в сетке указывает на класс типа MyViewModel
, который содержит пользовательский флаг IsDirty, который мы можем установить по требованию:
public bool IsDirty
{
get { return _isDirty; }
set
{
_isDirty = value;
OnPropertyChanged();
}
}
Приложение A: Дополнительные ссылки
- См. DevExpress: Как отключить выделенные / выделенные цвета строк.
- Смотрите DevExpress: Оптимизированный режим.
- См. DevExpress: DXGrid: Кажется, что DataTrigger не работает с UseLightweightTemplates = "All".
- См. DevExpress: привязка к свойству RowData.Row не обновляется при изменении определенного свойства строки данных.
- См. DevExpress: DxGrid: Сетка не обновляется, пока я не прокручиваю строку и выключаю один экран.
Приложение B: Другие решения
Это также работает большую часть времени, но не будет работать, если источником события является контекстное меню, поэтому это не рекомендуется:
<DataTrigger Binding="{Binding DataContext.IsDirty}" Value="True">
<Setter Property="Background" Value="{StaticResource GridRowIsDirty}" />
</DataTrigger>
Приложение C: AllowLiveDataShaping
Если триггер не срабатывает, попробуйте включить AllowLiveDataShaping="True"
в <GridControl>
, Однако старайтесь избегать этого, так как (теоретически) это влияет на скорость больших, сложных сеток (это не оказывает заметного влияния на большинство сеток разумного размера).
Приложение D: если ничего не помогает, используйте пользовательский шаблон ControlTemplate
С введением "UseLightweightTemplates" DevExpress сосредоточился на скорости. Однако методы, используемые для скорости, включают в себя отключение привязок, которые могут замедлить работу.
Это означает, что если мы что-то изменим в ячейке DxGrid, значение в ViewModel не изменится, пока пользователь не перейдет к следующей ячейке или строке. Это означает, что ViewModel отстает от того, что на самом деле находится в сетке.
Чтобы исправить это, единственное решение, которое я смог найти, - полностью обойти шаблоны DevExpress и использовать свои собственные. Это означает, что у DxGrid нет другого выбора, кроме как отображать пользовательский шаблон, который мгновенно обновляет ViewModel, как только пользователь его редактирует, а это означает, что цвет строки изменяется немедленно:
<dxg:GridControl Grid.Row="3" x:Name="TrsGridControl"
ItemsSource ="{Binding MyObservableCollection}"
VerticalAlignment="Stretch"
AllowLiveDataShaping ="True">
<dxg:GridControl.Resources>
<converter:TestConverter x:Key="TestConverter" />
<ControlTemplate x:Key="DisplayedOnTicketTrs">
<dxe:CheckEdit x:Name="DisplayedOnTicketCheckEdit" HorizontalAlignment="Center" IsChecked="{Binding RowData.Row.DisplayedOnTicket, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</ControlTemplate>
</dxg:GridControl.Resources>
<dxg:GridControl.View>
<dxg:TableView UseLightweightTemplates="All"/>
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn x:Name="DisplayedOnTicketTrs" DisplayTemplate="{StaticResource DisplayedOnTicketTrs}" Header="Displayed On Ticket?" HeaderToolTip="Displayed On Ticket?" AllowEditing="False"/>
Header ="Displayed On Ticket?"/>
<dxg:GridColumn x:Name="ColumnA" Header="ColumnA" FieldName="ColumnA" ReadOnly="True"/>
<dxg:GridColumn x:Name="ColumnB" Header="ColumnB" FieldName="ColumnB" ReadOnly="True"/>
</dxg:GridControl.Columns>
</dxg:GridControl>
После того, как я сделал это изменение, все начало работать:
- Когда флажок установлен, цвет фона меняется мгновенно (если мы добавим триггер для изменения цвета фона, выше).
- Редактирование DxGrid изменяет ViewModel мгновенно.
- Изменение ViewModel обновляет DxGrid мгновенно.
- Если ContextMenu обновляет ViewModel, то все просто работает.