DXGrid改变网格行DevExpress WPF的颜色

时间:2012-06-26 14:23:39

标签: xaml devexpress dxgrid

我拥有属性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 个答案:

答案 0 :(得分:6)

  

注意:这个答案很遗憾(参见我的其他答案)。

     

这个答案适用于v14.1之前的DevExpress版本,或DevExpress版本v14.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>   

答案 1 :(得分:1)

从DevExpress的v14.1开始,他们引入了Optimized Mode which uses Lightweight Templates。这使一切变得更快,但需要更改样式和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:其他链接

附录B:其他解决方案

这也适用于大部分时间,但如果事件的来源是通过上下文菜单,它将无法工作,因此不建议这样做:

 <DataTrigger Binding="{Binding DataContext.IsDirty}" Value="True">
    <Setter Property="Background" Value="{StaticResource GridRowIsDirty}" />
 </DataTrigger>

附录C:AllowLiveDataShaping

如果触发器未触发,请尝试启用AllowLiveDataShaping="True"中的<GridControl>。但是,尽量避免这种情况,因为它(理论上)会对大型复杂网格的速度产生影响(对大多数合理尺寸的网格没有明显的影响)。

附录D:如果所有其他方法都失败,请使用自定义ControlTemplate

随着&#34; UseLightweightTemplates&#34;的引入,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,那么一切正常。

答案 2 :(得分:0)

你应该写&#34; Row&#34;而不是&#34; DataContext&#34;