Revit API WPF C#:选中列表框中复选框的全部按钮

Revit API WPF C#: Check All button for Check Boxes in Listbox

我对使用 WPF 和 C# 进行编程还很陌生,我有一个关于自动检查列表框中所有复选框的可能性的问题。我正在为 Autodesk Revit 开发一个插件,在列表框中列出所有房间的名称后,我想使用“全部检查”按钮检查所有房间

我已经阅读了线程 ,但我仍然无法使其正常工作。有人可以帮我处理代码吗?

这是我所做的:

XAML:

<ListBox x:Name='roomlist'
              SelectionMode='Multiple'>
        <ListBox.ItemTemplate>
           <DataTemplate>
              <CheckBox IsChecked='{Binding IsChecked}'
                        Content="{Binding}" />
           </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.InputBindings>
           <KeyBinding Command="ApplicationCommands.SelectAll"
                       Modifiers="Ctrl"
                       Key="A" />
        </ListBox.InputBindings>
        <ListBox.CommandBindings>
           <CommandBinding Command="ApplicationCommands.SelectAll" />
        </ListBox.CommandBindings>
     </ListBox>

C#

public partial class RoomsDistance_Form : Window
{
    UIDocument _uidoc;
    Document _doc;

    public RoomsDistance_Form(Document doc, UIDocument uidoc) 
    {
        InitializeComponent();

        FilteredElementCollector collector = new FilteredElementCollector(doc)
            .WhereElementIsNotElementType()
            .OfCategory(BuiltInCategory.OST_Rooms);

        List<String> myRooms = new List<String>();
        foreach (var c in collector)
        {
            myRooms.Add(c.Name);
        }
        myRooms.Sort();
        roomlist.ItemsSource = myRooms;
    }


    private void checkAllBtn_Click(object sender, RoutedEventArgs e)
    {
        
        foreach (CheckBox item in roomlist.Items.OfType<CheckBox>())
        {
            item.IsChecked = true;
        }
    }

    public class Authority : INotifyPropertyChanged
    {
        private bool isChecked;
        public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                isChecked = value;
                NotifyPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

}

非常感谢您的帮助!

在您链接到的线程中,他们在数据对象(权限)上设置“IsChecked”,而不是 CheckBox 控件本身。

foreach (var a in authorityList)
{
     a.IsChecked = true;
}

您有一个到 IsChecked 的绑定,它将在调用 NotifyPropertyChanged() 时更新 Checkbox 控件。

在我失去理智之后,我通过避免列表框解决了我的问题。我只是在 StackPanel 中添加了单个复选框。

XAML:

<ScrollViewer Margin='10,45,10,100'
                BorderThickness='1'>
     <StackPanel x:Name='stack'
                 Grid.Column='0'></StackPanel>
  </ScrollViewer>

C#:

foreach (var x in myRooms)
        {
            CheckBox chk = new CheckBox();
            chk.Content = x;
            stack.Children.Add(chk);
        }

这不是我想要的,但现在它可以工作了,这就是重点。

感谢您的帮助!

我通常通过以下方式使用 CheckBoxList:

在xaml中:

<ListBox ItemsSource="{Binding ListBoxItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> //+some dimensional properties
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

在xaml.cs中:

public partial class MyWindow : Window
{
    public ViewModel ViewModel {get; set; }

    public MyWindow(ViewModel viewModel)
    {
        //keep all the mess in ViewModel, this way your xaml.cs will not end up with 1k lines
        ViewModel = viewModel;
        DataContext = ViewModel;
        InitializeComponent();
    }

    void BtnClick_SelectAll(object sender, RoutedEventArgs e)
    {
        ViewModel.CheckAll();
    }
}

ViewModel 准备:

public class ViewModel
{
    public List<ListBoxItem> ListBoxItems { get; set; }

    //InitializeViewModel()...
    //UpdateViewModel()...
    //other things....
    
    public void CheckAll()
    {
        foreach (var item in ListBoxItems) 
        {
            item.IsSelected = true;
        }    
    }

public class ListBoxItem : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            if (_isSelected != value)
            {
                _isSelected = value;
                OnPropertyChanged(nameof(IsSelected));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}