wpf Revit 2021.1 -选择行时,DataGridRow.IsSelected属性不总是为真

c86crjj0  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(156)

我到处找遍了,但还是找不到解决问题的办法。我正在使用C#和WPF为Revit 2021.1编写简单的插件。
下面是我的.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>

DataGrid绑定到ViewModel中的ElementParameterWrapper对象列表。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; }
}

因此,IsObjectSelected属性绑定到DataGridRow.IsSelected属性。但是!ElementParameterWrapper属性IsObjectSelected并不总是为true(即使已选中)。在图片上可以看到ElementParameterWrapper对象是如何被选择的(有一些列表绑定到datagrid,并且在每个ElementParameterWrapper对象上都被选择)-Revit Plugin Window
所以我不太清楚为什么IsObjectSelected属性有时为true,有时为false(即使选中了行)。
我尝试将其绑定到单个对象(而不是对象列表),但仍然不起作用。此外,我使用了几次 Package 器,它总是工作.这是否与我从两个DataGrid中选择每个对象有关?谢谢你,谢谢

hxzsmxv2

hxzsmxv21#

您必须在 Package 器类中实现INotifyPropertyChanged,才能使任何双向绑定工作。参见example on MSDN
此外,不确定绑定到DataGridRowIsSelected属性是否是正确的方法,而是尝试在ViewModel(托管ListOfElementParameterWrappers的类)中创建一个SelectedItem属性,并将其绑定到xaml中DataGridSelectedItem属性。ListOfElementParameterWrappers的类型应该是ObservableCollection<ElementParameterWrapper>,而不是一般列表(see this article)。
生成的代码可能如下所示:

wrapper类:

public class ElementParameterWrapper:INotifyPropertyChanged
{
    public ElementParameterWrapper(Parameter parameter)
    {
        Name = parameter.Definition.Name;
        Id = parameter.Id;
        if (parameter.IsShared)
        {
            GUID = parameter.GUID;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    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;
            OnPropertyChanged();
        }
    }
    
    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

ViewModel类:

public class MyViewModel : INotifyPropertyChanged
{
    public MyViewModel (ICollection wrapperCollection){
        ListOfElementParameterWrappers = new ObservableCollection<ElementParameterWrapper>(wrapperCollection);
        SelectedItem = ListOfElementParameterWrappers.FirstOrDefault();
    }
      
    public ObservableCollection<ElementParameterWrapper> ListOfElementParameterWrappers {get; set;}
      
    private ElementParameterWrapper _selecteItem;
    //this property keeps track of the currently selected item in the DataGrid
    public ElementParameterWrapper SelectedItem {
        get {return _selectedItem;}
        set {
            _selectedItem = value;
            //If you need to also change the value of the IsSelected
            //property of the selected item you can do something like this
            foreach (var item in ListOfElementParameterWrappers){
                item.IsObjectSelected= false;
            }
            _selectedItem.IsObjectSelected= true;
            //finally fire the PropertyChanged event
            OnPrepertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

xaml

<DataGrid Grid.Row="1"
          Grid.Column="0"
          HorizontalAlignment="Left"
          Margin="10,0,10,10"
          ItemsSource="{Binding ListOfElementParameterWrappers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
 
          SelecteItem="{Binding SelectedItem, 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>

相关问题