Revit 2021.1:DataGridRow选中时IsSelected属性不始终为True
问题解决:DataGrid行选中状态与ViewModel属性绑定不同步
问题描述
开发Revit 2021.1插件时,使用WPF DataGrid将行的IsSelected属性绑定到ElementParameterWrapper类的IsObjectSelected属性,但出现异常:即使DataGrid行已显示选中状态,IsObjectSelected有时仍为False。怀疑该问题与同时在两个DataGrid中选择对象有关。
涉及代码
XAML中的DataGrid及RowStyle
<DataGrid Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Margin="10,0,10,10" ItemsSource="{Binding ListOfElementParameterWrappers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" RowStyle="{StaticResource RowToBeSelectedStyle}" AutoGenerateColumns="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" CanUserAddRows="False" CanUserResizeColumns="False" CanUserSortColumns="False" IsReadOnly="False" SelectionMode="Single" SelectionUnit="FullRow"> </DataGrid> <Window.Resources> <Style x:Key="RowToBeSelectedStyle" TargetType="{x:Type DataGridRow}"> <Setter Property="IsSelected" Value="{Binding IsObjectSelected}"/> </Style> </Window.Resources>
ElementParameterWrapper类代码
public ElementParameterWrapper(Parameter parameter) { Name = parameter.Definition.Name; Id = parameter.Id; if (parameter.IsShared) { GUID = parameter.GUID; } } public string Name { get; set; } public ElementId Id { get; set; } public Guid GUID { get; set; } private bool isObjectSelected; public bool IsObjectSelected { get { return isObjectSelected; } set { isObjectSelected = value; } }
解决方案
1. 明确绑定的双向模式与更新时机
默认绑定可能未启用双向同步,或更新触发时机滞后。修改RowStyle中的绑定配置:
<Style x:Key="RowToBeSelectedStyle" TargetType="{x:Type DataGridRow}"> <Setter Property="IsSelected" Value="{Binding IsObjectSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </Style>
2. 实现INotifyPropertyChanged接口
ElementParameterWrapper未实现属性变更通知,会导致UI与ViewModel状态同步中断。修改类代码:
public class ElementParameterWrapper : INotifyPropertyChanged { public ElementParameterWrapper(Parameter parameter) { Name = parameter.Definition.Name; Id = parameter.Id; if (parameter.IsShared) { GUID = parameter.GUID; } } public string Name { get; set; } public ElementId Id { get; set; } public Guid GUID { get; set; } private bool isObjectSelected; public bool IsObjectSelected { get { return isObjectSelected; } set { if (isObjectSelected != value) { isObjectSelected = value; OnPropertyChanged(nameof(IsObjectSelected)); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
3. 解决多DataGrid选择冲突
若两个DataGrid共享关联数据源,易出现选中状态互相覆盖:
- 确保两个DataGrid的
SelectionMode和SelectionUnit配置一致; - 避免两个DataGrid绑定的集合存在重复对象引用;
- 在ViewModel中为每个DataGrid单独维护选中项属性,替代依赖对象自身的
IsObjectSelected:
对应XAML中给每个DataGrid绑定// ViewModel中新增两个选中项属性 private ElementParameterWrapper _selectedItemGrid1; public ElementParameterWrapper SelectedItemGrid1 { get => _selectedItemGrid1; set { _selectedItemGrid1 = value; OnPropertyChanged(nameof(SelectedItemGrid1)); // 可选:同步更新对象选中状态 if (_selectedItemGrid1 != null) _selectedItemGrid1.IsObjectSelected = true; } } private ElementParameterWrapper _selectedItemGrid2; public ElementParameterWrapper SelectedItemGrid2 { get => _selectedItemGrid2; set { _selectedItemGrid2 = value; OnPropertyChanged(nameof(SelectedItemGrid2)); if (_selectedItemGrid2 != null) _selectedItemGrid2.IsObjectSelected = true; } }SelectedItem:<!-- 第一个DataGrid --> <DataGrid ... SelectedItem="{Binding SelectedItemGrid1, Mode=TwoWay}" /> <!-- 第二个DataGrid --> <DataGrid ... SelectedItem="{Binding SelectedItemGrid2, Mode=TwoWay}" />
4. 处理Revit线程调度问题
Revit API要求操作必须在主线程执行,若绑定涉及Revit对象,需确保数据更新在正确线程:
// 使用Dispatcher确保在UI线程更新属性 Application.Current.Dispatcher.Invoke(() => { // 更新ViewModel属性或集合的操作 });
内容的提问来源于stack exchange,提问作者jazlik
相关产品推荐
相关产品推荐

