WPF 动态创建按钮和扩展器控件

本文关键字:扩展器 控件 按钮 动态 创建 WPF | 更新日期: 2023-09-27 18:36:28

我正在创建动态按钮,每个按钮下方都有扩展器。当单击每个按钮时,我希望此按钮下方的扩展器将打开。我怎么知道在每个按钮点击中要打开哪个扩展器?

public partial class MainWindow : Window
{
    List<List<string>> Buttons;

    public MainWindow()
    {
        InitializeComponent();
        Buttons = new List<List<string>>();
        /////////////////////////////////////////
        List<string> lst1 = new List<string>();
        lst1.Add("main1");
        lst1.Add("a1");
        lst1.Add("a2");
        lst1.Add("a3");
        lst1.Add("a4");
        Buttons.Add(lst1);
        /////////////////////////////////////////
        List<string> lst2 = new List<string>();
        lst2.Add("main2");
        lst2.Add("b1");
        lst2.Add("b2");
        lst2.Add("b3");
        lst2.Add("b4");
        Buttons.Add(lst2);
        /////////////////////////////////////////
        List<string> lst3 = new List<string>();
        lst3.Add("main3");
        lst3.Add("c1");
        lst3.Add("c2");
        lst3.Add("c3");
        lst3.Add("c4");
        Buttons.Add(lst3);
        for (int i = 0; i < Buttons.Count; i++)
        {
            Button newBtn = new Button();
            newBtn.Content = Buttons[i][0];
            newBtn.Name = "Button" + i.ToString();
            newBtn.Height = 23;
            stackPanel1.Children.Add(newBtn);
            newBtn.Click += new RoutedEventHandler(newBtn_Click);

            Expander expader = new Expander();
            StackPanel newStck = new StackPanel();
            for (int j = 1; j < Buttons[i].Count; j++)
            {
                Button newBtnIn = new Button();
                newBtnIn.Content = Buttons[i][j];
                newBtnIn.Name = "Button" + j.ToString();
                newBtnIn.Height = 23;
                newBtnIn.Width = 100;
                newStck.Children.Add(newBtnIn);
            }
            expader.Content = newStck;
            stackPanel1.Children.Add(expader);
        }

    }
    private void newBtn_Click(object sender, RoutedEventArgs e)
    {
         //open specific expander below button
    }
}

WPF 动态创建按钮和扩展器控件

您可以使用按钮的 Tag 属性为按钮提供对其扩展器的引用。一个可行的解决方案是:

 public partial class MainWindow : Window
{
    List<List<string>> Buttons;

    public MainWindow()
    {
        InitializeComponent();
        Buttons = new List<List<string>>();
        /////////////////////////////////////////
        List<string> lst1 = new List<string>();
        lst1.Add("main1");
        lst1.Add("a1");
        lst1.Add("a2");
        lst1.Add("a3");
        lst1.Add("a4");
        Buttons.Add(lst1);
        /////////////////////////////////////////
        List<string> lst2 = new List<string>();
        lst2.Add("main2");
        lst2.Add("b1");
        lst2.Add("b2");
        lst2.Add("b3");
        lst2.Add("b4");
        Buttons.Add(lst2);
        /////////////////////////////////////////
        List<string> lst3 = new List<string>();
        lst3.Add("main3");
        lst3.Add("c1");
        lst3.Add("c2");
        lst3.Add("c3");
        lst3.Add("c4");
        Buttons.Add(lst3);
        for (int i = 0; i < Buttons.Count; i++)
        {
            Button newBtn = new Button();
            newBtn.Content = Buttons[i][0];
            newBtn.Name = "Button" + i.ToString();
            newBtn.Height = 23;
            stackPanel1.Children.Add(newBtn);
            newBtn.Click += new RoutedEventHandler(newBtn_Click);

            Expander expader = new Expander();
            StackPanel newStck = new StackPanel();
            for (int j = 1; j < Buttons[i].Count; j++)
            {
                Button newBtnIn = new Button();
                newBtnIn.Content = Buttons[i][j];
                newBtnIn.Name = "Button" + j.ToString();
                newBtnIn.Height = 23;
                newBtnIn.Width = 100;
                newBtn.Tag = expader;
                newBtn.Click+=newBtn_Click;
                newStck.Children.Add(newBtnIn);
            }
            expader.Content = newStck;
            stackPanel1.Children.Add(expader);
        }

    }
    private void newBtn_Click(object sender, RoutedEventArgs e)
    {
        Button b = sender as Button;
        if (b == null)
            return;
        Expander ex = b.Tag as Expander;
        if (ex == null)
            return;
        ex.IsExpanded = !ex.IsExpanded;
    }
}
我想

你应该使用ToggleButton而不是Button这允许您处理IsChecked状态,从而展开/折叠底层Expander控件。
因此,您将能够在以下ToggleButtonExpander中定义DataTemplate

<DataTemplate>
   <StackPanel>
     <ToggleButton x:Name="expandButton" IsChecked="false"/>
     <Expander IsExpanded="{Binding IsChecked, ElementName=expandButton}">
        <TextBlock TextWrapping="Wrap">
             Lorem ipsum dolor sit amet, consectetur
             adipisicing elit, sed do eiusmod tempor incididunt ut
             labore et dolore magna aliqua
        </TextBlock>
     </Expander>
   </StackPanel>
</DataTemplate>

之后,您应该考虑使用 ListViewListBox 或任何其他合适的控件,并将ItemsSource设置为按钮列表。这将为您提供干净的设计,而无需大量代码隐藏,这并不像实践所显示的那样好。