标签页内的定位按钮不起作用

标签页内的定位按钮不起作用

本文介绍了标签页内的定位按钮不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有按钮和tabcontrol / tabpage组件的表单。该按钮位于表单上,而不是tabcontrol中。我正在尝试将按钮与tabcontrol相关联。我被告知不要使用Controls.Add()方法。



我正在使用Point类来确定tabcontrol的.X .Y。但是,当我单击tabpage index 0时,我将.Left和.Top属性设置为0并且它引用了表单的左上角,而不是tabcontrol。我在网上搜索试图找到一种方法来关联tabcontrol相关的按钮位置,但我找不到参考。使用Controls.Add()是获取按钮引用其与tabcontrol的位置关系的唯一方法吗?



感谢您的帮助。



I have a form with a button and a tabcontrol/tabpage component. The button is on the form, not in the tabcontrol. I'm trying to position the button in relation to the tabcontrol. I was told not to use the Controls.Add() method.

I'm using the Point class to determine the .X .Y of the tabcontrol. However, when I click on tabpage index 0, I set the .Left and .Top properties to 0 and its referencing the top left corner of the form, not the tabcontrol. I searched online trying to find a way to associate the button location in relation to the tabcontrol but I could not find a reference. Is using the Controls.Add() the only way to get the button to reference its position relationship to the tabcontrol?

Thanks for any help.

private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
    Point locPoint = this.Location;//referencing tabControl1???
    int locLeft = locPoint.X;
    int locTop = locPoint.Y;
    if (tabControl1.SelectedIndex == 0)
    {
        button1.Left = 0;// referencing form!
        button1.Top = 0;
    }
    if (tabControl1.SelectedIndex == 1)
    {
        button1.Left = locLeft;
        button1.Top = locTop;
    }
    if (tabControl1.SelectedIndex == 2)
    {
        button1.Left = locLeft;
        button1.Top = locTop;
    }
}

推荐答案

private void tabControl1_Selected(object sender, TabControlEventArgs e)
        {
            Point locPoint = this.tabControl1.Location;//referencing tabControl1???
            int locLeft = locPoint.X;
            int locTop = locPoint.Y;

            button1.Left = locLeft;
            button1.Top = locTop;

        }

会这样做。如果你在每个标签上使用不同的位置,你只需要查看selectedIndex - 但是从那里开始简单并构建。

目前这个代码会遮挡标签,所以你不能选择更多,所以考虑改变.Top位置(例如+50)



其次 - 不确定为什么你被告知不要直接把控件放在标签页上 - 你可以像添加到表单一样轻松地动态执行此操作 - []并且你可以获得所有令人讨厌的可见性,具体取决于免费选择哪个选项卡

will do it. You only need to look at the selectedIndex if you're using a different position per tab - but start simple and build up from there.
As it stands this code will obscure the tab so you can't select any more, so consider changing the .Top position (e.g. + 50)

Secondly - not sure why you were told to not put controls directly onto the tabpages - you can do this dynamically just as easily as adding them to the form - clickety[^] and you get all that pesky visibility depending on which tab selected for free


private Button btnToBeAdded;

private int btnXLocation = 30;
private int btnStartYLocation = 30;
private int btnYOffset = 40;

private void addButtonsToTabPages_Click(object sender, EventArgs e)
{
    for (int i = 0; i < tabControl1.TabPages.Count; i++)
    {
        // create the Button
        btnToBeAdded = new Button();

        // set visual attributes of the Button
        btnToBeAdded.BackColor = Color.AliceBlue;

        // name it ?, set it's Text
        btnToBeAdded.Name = "addedBtn" + i.ToString();
        btnToBeAdded.Text = "click Me";

        // give the button a tag
        btnToBeAdded.Tag = i;

        // add the Button to the TabPage
        tabControl1.TabPages[i].Controls.Add(btnToBeAdded);

        // set its location
        btnToBeAdded.Location = new Point(btnXLocation, btnStartYLocation + (btnYOffset * i));

        // give it a Click EventHandler
        btnToBeAdded.Click += btnToBeAdded_Click;
    }
}

private void btnToBeAdded_Click(object sender, EventArgs e)
{
    Button btnClicked = sender as Button;

    // put some code here to be executed when the Button
    // on every TabPage is clicked ?
    // ...

    // make sure you handle every possible index value
    switch (Convert.ToInt32(btnClicked.Tag))
    {
        case 0:
            // call your code if added Button on first TabPage is clicked
            firstTabPageButtonDoSomething();
            break;
        case 1:
            break;
        case 2:
            break;
        // case #n:
            //break;
        default:
            // you have a problem
            throw new IndexOutOfRangeException();
    }
}

private void firstTabPageButtonDoSomething()
{
    MessageBox.Show("Button on first TabPage clicked");
}

讨论:注意添加到每个TabPage的每个Button的Tag属性是如何设置为一个数字值,用于标识TabControl中TabPage的索引。



然后,添加的所有按钮都可以共享相同的'Click EventHandler:使用Tag属性在该EventHandler中...必须将其转换为整数,因为Tag属性是Object类型。然后,您可以触发执行任何您想要每个Button执行的操作。

Discussion: note how the Tag Property of each Button added to each TabPage was set to a numeric value that identified the index of the TabPage in the TabControl.

Then, all Buttons added can share the same 'Click EventHandler: in that EventHandler by using the Tag Property ... had to convert it to an integer because a Tag Property is of type Object ... you can then trigger execution of whatever you want each Button to do.


private TabPage currentTabPage;

private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
    if (! (currentTabPage == null))
    {
        // here's where you write the code to save
        // whatever information about the previously selected
        // TabPage you want to save
        // ... save whatever ...

        currentTabPage.Controls.Remove(panel1);
    }

    currentTabPage = e.TabPage;

    // see Discussion below
    tabControl1.SuspendLayout();
    currentTabPage.SuspendLayout();
    panel1.SuspendLayout();
    this.SuspendLayout();

    // here's where you write code to configure
    //  Controls in panel1 based on whatever you saved previously
    // ... configure Controls on panel1 to whatever ...

    // for educational purposes only
    Console.WriteLine("selected tabPage: " + currentTabPage.Name);
    Console.WriteLine("selected tabPage's Tab rectangle: "
        + tabControl1.GetTabRect(e.TabPageIndex));
    Console.WriteLine();

    currentTabPage.Controls.Add(panel1);
    // probably unnecessary, but why not ?
    panel1.Dock = DockStyle.Fill;

    // see Discussion below
    tabControl1.ResumeLayout(false);
    tabPage1.ResumeLayout(false);
    panel1.ResumeLayout(false);
    panel1.PerformLayout();
    this.ResumeLayout(false);
    this.PerformLayout();
}

讨论:



0.你在使用布局时所做的那些时髦的东西是什么?



嗯,这正是Windows Form Designer.cs文件处理布局的方式,你看到的可能是过度杀戮,但我把它放进去(希望如此) )这个回复对CP有更多的教育价值。



事实上,即使Form的DoubleBuffered属性设置为'true,并且使用上面的代码,当你从TabPage切换时,你会看到一个轻微的跳跃运行时到TabPage。如果它困扰你,请务必并写下MS:



1.如何管理保存和恢复问题的提示如何状态一组控件现在自动移动到当前选定的TabPage?



1.a.取决于你需要保存的内容:例如,你是否想要保存TreeView文件浏览器的整个状态:这不太可能,因为用户上次打开他的C /.../时有效的文件夹和文件。 ../.../WhatEverFolder可能已经改变了。因此,在这种情况下,您只需要调用保存文件夹路径(字符串)的代码,然后重新加载TreeView。



1.b.无论你创建什么数据结构来保存任何已保存的数据以供重复使用:它的关键显然是TabPage的索引。看一下在我的第一个解决方案中添加的每个控件中设置Tab属性的用法,以及稍后使用该Tab属性在switch / case语句中进行差异操作。



1.c.我的假设是你永远不会想要这样一个复杂的(嵌套的)控件集(面板中包含控件的面板等),你需要以递归方式解析外部面板的全部内容:事实上,如果我看到类似的东西,我会立即认为这是糟糕的设计。所以,在设计时尽你所能标记(通过设置Control的Tag属性)控制你需要保存状态,并将它们存储在List< Control>中。



1.d.另一种可能的设计是定义您自己的继承自WinForms控件的控件,以及用于保存和恢复的额外字段,属性或序列化工具等。

Discussion:

0. what's all that funky stuff you are doing with Layout ?

well, that's exactly the way the Windows Form Designer.cs files handle Layout, and what you see may be "overkill" but I am putting that in so (hopefully) this reply has more educational value on CP.

The fact is that even with the Form's DoubleBuffered property set to 'true, and using the above code, you will see a slight "jump" as you switch from TabPage to TabPage at run-time. Be sure and write MS about that, if it bothers you :)

1. how about a hint on how to manage the issue of saving, and restoring, the "state" of the one set of Controls that are now automatically "moved into" the current selected TabPage ?

1.a. depends on what you need to save: do you, for example, want to save the entire state of the TreeView file-browser: that's unlikely because the folders and files that were valid when the user last opened his C/.../.../.../WhatEverFolder may have changed. So, in that case you'll just need to call the code that takes a saved folder path (string), and reload the TreeView.

1.b. whatever data-structure you do create to hold any saved data for re-use: the "key" to it will be obviously the index of the TabPage. look at the use of setting the Tab property in each control added in my first solution on this thread, and, later, using that Tab property to take differential action in a switch/case statement.

1.c. my assumption is that you'd never want to have such a complex (nested) set of Controls (Panels within Panels that hold Controls, etc.) that you'd need to recursively parse the entire contents of the outer Panel: in fact, if I saw something like that, I'd immediately think it was bad design. so, do whatever you can at design-time to "mark" (by setting the Control's Tag property) Controls you will need to save state from, and store them in a List<Control>.

1.d. another possible design is to define your own Controls that inherit from the WinForms Controls, and extra fields, and properties, or serialization facilities, etc., to use in saving and restoring.


这篇关于标签页内的定位按钮不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 22:15