2

我正在使用 DevExpress 开发 WPF 应用程序,并且还使用 mvvm 模式,并且遇到以下问题:

  • 我有一个具有布尔属性的视图模型(例如 IsChecked)
  • 我有一个视图,它是一个绑定到上述视图模型项的集合的 devexpress 数据网格
  • 该 devexpress 数据网格的一行属于复选框类型,并且绑定到 IsChecked 属性
  • 如果 IsChecked 为真,我有一个 devexpress 网格行的数据模板,用于在行中显示一行

当我选中/取消选中数据网格中的复选框列时,所有这些都可以正常工作......问题是当我更改模型属性的值时:视图没有改变......

该模型实现INotifyPropertyChanged.

似乎是 DevExpress 为每个项目做了一个包装器,然后当模型的属性发生变化时不会通知视图。

4

1 回答 1

5

在搜索 DevExpress 的支持中心后,我找不到任何可以帮助我解决这个问题的东西。但是多亏了这个不错的应用程序(Snoop),我得到了解决。

问题是 DevExpress 的网格集合的行为与其他 WPF 的标准集合不同。在任何 WPF 的集合中,每一行(或集合中的项)都在DataContextViewModel(或集合类型的任何类)中。DevExpress 的网格不是那样工作的......

GridRowDevExpress 网格中的每个项目在 中都有一个类型RowData的对象DataContext,每个单元格(类型为GridCellContentPresenter)都有一个类型为 的对象EditGridCellData。正如我们所看到的,这些对象与我们的集合不同。

那么我们如何在视图模型和网格中的视图行或单元格项之间进行双向绑定呢?

如果我们正在制作一个行模板:

DataContext每行中的对象是类型RowData。这个类型有一个名为 的属性DataContext,这个属性是类型的RowTypeDescriptor(就像我们的集合类型的包装器)。这不适用于我们的绑定。但是该类型RowData有一个属性 namde Row,我们可以在其中找到我们集合的类型行对象,所以我们唯一要做的就是绑定到这个属性。例如,在这种情况下,如果 bool 字段设置为 true,我们希望一条线穿过我的行:

<DataTemplate x:Key="myRowTemplate">
        <Grid>
            <dx:MeasurePixelSnapper>
                <ContentPresenter x:Name="defaultRowPresenter" Content="{Binding}" ContentTemplate="{Binding View.DefaultDataRowTemplate}" />
            </dx:MeasurePixelSnapper>               
            <Path Data="M5.496,10.5 L508,10.5" Fill="#FFF" HorizontalAlignment="Stretch" Height="1" Stretch="Fill" Stroke="#FF040404" VerticalAlignment="Center" Width="Auto" Margin="0" Visibility="{Binding Row.AnyModelBoolProperty, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource IntToVisibilityConverter}}"/>
        </Grid>
    </DataTemplate>

如果我们正在制作一个单元格模板:

在这种情况下有点复杂。因为该对象EditGridCellData没有任何可以找到集合对象类型的属性。我们在这里唯一能找到的是一个名为的属性Data,我们可以在其中找到 type 的对象RowTypeDescriptor,所以不能正常工作。我们需要使用祖先类型绑定来解决这个问题。看这个例子:

    <dxg:GridColumn x:Name="dateRow" FieldName="Date" Header="Date">
                    <dxg:GridColumn.CellTemplate>
                        <DataTemplate>
                            <dxe:DateEdit x:Name="PART_Editor" DateTime="{Binding DataContext.Row.Date, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type dx:StackVisibleIndexPanel}}}" IsEnabled="{Binding DataContext.Row.DateEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type dx:StackVisibleIndexPanel}}}" MinValue="{Binding DataContext.Row.DateMinValue, RelativeSource={RelativeSource AncestorType={x:Type dx:StackVisibleIndexPanel}}}"/>
                        </DataTemplate>
                    </dxg:GridColumn.CellTemplate>
    </dxg:GridColumn>

在这里,我们有一个日期控件,它将绑定到模型并得到正确的通知。希望这对遇到此问题的每个人都有用。这是一个真正的头痛。

于 2013-01-23T18:29:21.907 回答