簡體   English   中英

在 WPF/C# 中,如何訪問動態生成的控件的元素或以其他方式向它們添加單擊事件?

[英]In WPF/C#, how do I access elements of dynamically generated controls or otherwise add click events to them?

我正在使用自定義控件 class 來構建具有不同細節和 OnClick 操作的外觀相似的控件。 除了看起來漂亮之外,只有 function 的控件用於切換黃色按鈕,因此它看起來像現代的切換按鈕控件(如 Android 設置或其他)。

主要的 output 看起來像這樣: 帶有自定義控件的主輸出

我想做的是弄清楚如何將“onclick”邏輯從控件中移出並放入主文件中,以便我可以正確地響應它。 我最初讓它響應它自己在矩形和橢圓上的點擊事件,如下所示:

    public partial class FixerBox : UserControl
    {
        Thickness btnDotOn = new Thickness(-60, 0, 0, 0);
        Thickness btnDotOff = new Thickness(0, 0, -60, 0);
        SolidColorBrush dotOn = new SolidColorBrush(Color.FromRgb(84, 130, 53));
        SolidColorBrush dotOff = new SolidColorBrush(Color.FromRgb(207, 178, 76));
        SolidColorBrush bkOn = new SolidColorBrush(Color.FromRgb(226, 240, 217));
        SolidColorBrush bkOff = new SolidColorBrush(Color.FromRgb(255, 242, 204));
        
        public bool IsOn { get; set; } = false;
        
        public FixerBox(Dictionary<string,string> deets)
        {
            InitializeComponent();
            btnOff();
            this.Name = deets["Name"];
            this.FixerTitle.Text = deets["Title"];
            this.FixerDesc.Text = deets["Description"];
            this.FixerTags.Text = deets["Tags"];
            this.FixerImg.Source = new BitmapImage(new Uri(deets["Img"], UriKind.Relative));
        }

        public void btnOn() 
        {
            IsOn = true;
            FixBtnBk.Fill = bkOn;
            FixBtnBk.Stroke = dotOn;
            FixBtnDot.Fill = dotOn;
            FixBtnDot.Margin = btnDotOn;
        }
        public void btnOff() 
        {
            IsOn = false;
            FixBtnBk.Fill = bkOff;
            FixBtnBk.Stroke = dotOff;
            FixBtnDot.Fill = dotOff;
            FixBtnDot.Margin = btnDotOff;
        }

        private void FixBtnBk_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //if (isOn)
            //{
            //  btnOff();
            //}
            //else
            //{
            //  btnOn();
            //}
        }
        private void FixBtnDot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FixBtnBk_MouseLeftButtonDown(sender, e);
        }

    }

我現在已經注釋掉了點擊事件,所以我可以嘗試從外部觸發相同的效果:

        // The click event I'm trying to build
        private void fixClick(object sender, EventArgs e)
        {
            StatusBox.Text = "CLICK WORKS";
            FixerBox whichFix = (FixerBox)sender;
            if (whichFix.IsOn)
            {
                whichFix.btnOff();
            }
            else
            {
                whichFix.btnOn();
            }
        }

        // The constructor of my app
        public MainWindow()
        {
            InitializeComponent();
            // fixNames is a dictionary containing details of each control
            var fixNames = fixers.FixerNames();
            foreach (string key in fixNames)
            {
                var temp = fixers.GetFix(key);
                // Be sure to pass this along as well
                temp["Name"] = key;
                fixerBoxes[key] = new FixerBox(temp);
                fixerBoxes[key].FindName("FixBtnBk") = new EventHandler(fixClick);
                FixersArea.Children.Add(fixerBoxes[key]);
            }           
        }

上面是我的主要應用程序構造函數,我在其中生成所有控件。 問題是在我設置事件處理程序的那一行,我無法弄清楚如何讓它真正起作用。 FindName 應該獲得特定的控件,但它沒有單擊事件或鼠標按下或任何東西。 如何將我的自定義點擊事件附加到每個控件?

我這樣做的原因是因為隨着切換按鈕,我希望它實際進行系統更改和注冊表更新以響應單擊哪個控件。 我可以將所有響應保留在 class 中,並將它們包含在自定義控件中,但從系統資源的角度和編程的角度來看,這似乎很草率。

相反,如果我能弄清楚如何訪問動態控件的各種元素並向它們添加單擊事件(或任何等效的解決方法),那似乎更好。

如何訪問動態生成的控件的元素或以其他方式向它們添加點擊事件。 我想做的是弄清楚如何將“onclick”邏輯從控件中移出並放入主文件中,以便我可以正確地響應它。

正如我在上面的評論中提到的,您可以創建您可以訂閱的公共事件,並根據需要響應這些事件。

在你的FixerBox class 中:

  • 添加事件: public event RoutedEventHandler MouseLeftBtnDown;

  • 在需要時調用事件:

     private void FixerBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { MouseLeftBtnDown?.Invoke(this, new RoutedEventArgs()); }

在您的 class 中,您想訂閱這個新活動:

foreach (string key in fixNames)
            {
                var temp = fixers.GetFix(key);
                // Be sure to pass this along as well
                temp["Name"] = key;
                fixerBoxes[key] = new FixerBox(temp);
                fixerBoxes[key].MouseLeftBtnDown += fixClick;
                FixersArea.Children.Add(fixerBoxes[key]);
            }  

您的常規簽名也需要更改:

 private void fixClick(object sender, RoutedEventArgs e)

這應該可以幫助您入門,如果您有任何疑問,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM