【问题标题】:Revit API WPF C#: Check All button for Check Boxes in ListboxRevit API WPF C#:在列表框中检查复选框的所有按钮
【发布时间】:2021-03-29 20:26:53
【问题描述】:

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

我已经阅读了at this page 的帖子,但我仍然无法让它工作。有人可以帮我写代码吗?

这是我所做的:

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));
            }
        }
    }

}

非常感谢您的帮助!

【问题讨论】:

    标签: c# wpf xaml revit-api


    【解决方案1】:

    我通常以如下方式使用 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));
        }
    }
    

    【讨论】:

      【解决方案2】:

      在失去理智之后,我通过避免使用列表框解决了我的问题。我只是在 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);
              }
      

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

      感谢您的帮助!

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2012-12-12
          • 1970-01-01
          • 2011-08-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-27
          相关资源
          最近更新 更多