精华内容
下载资源
问答
  • ToolStripStatusLabel 没有 InvokeRequired 属性的解决办法当编写多线程程序时,你希望在线程中修改 Form 窗体上的控件的文本等属性,但你会得到一个错误:线程间操作无效: 从不是创建控件“xxx”的线程访问它。...

    ToolStripStatusLabel 没有 InvokeRequired 属性的解决办法

    当编写多线程程序时,你希望在线程中修改 Form 窗体上的控件的文本等属性,

    但你会得到一个错误:线程间操作无效: 从不是创建控件“xxx”的线程访问它。

    引发了“Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException”类型的异常.


    这时有一个解决办法就是使用委托来进行 Invoke 调用,

    但是你会发现 ToolStripStatusLabel 没有 InvokeRequired 属性!

    这个问题存在的原因是什么呢?

    我们看看 Textbox 的继承关系:

    public abstract class TextBoxBase : Control

    再看看 ToolStripStatusLabel  的继承关系:

    public abstract class ToolStripItem : Component, IDropTarget, IComponent, IDisposable
    再看看 ToolStripStatusLabel  的容器 StatusStrip 的继承关系:

    public class ScrollableControl : Control, IComponent, IDisposable
    我们会发现,这是因为ToolStripItem 是一个组件 Component,而不是一个控件 Control。
    解决办法:

    方法其实也比较简单,尝试在拥有它们的工具条、状态栏(StatusStrip)上调用扩展方法,并调整委托方法。

    实例一:

    public class MyForm : System.Windows.Forms.Form {
                 
        //UI 元素
        private Label lblStatus;
         
        private ProgressBar progressBar1;
     
        //Delegate
        private delegate void MyProgressEventsHandler(
            object sender, MyProgressEvents e);
     
         
         private void UpdateUI(object sender, MyProgressEvents e) {
            lblStatus.Text = e.Msg;
            myProgressControl.Value = e.PercentDone;
        }
     
       //ShowProgress 现在可以记录为可从任何线程调用的公共方法。
        public void ShowProgress(string msg, int percentDone) 
       {
        if(InvokeRequired)
        {
           System.EventArgs e = new MyProgressEvents(msg, percentDone);
               object[] pList = { this, e };
     
               BeginInvoke(new MyProgressEventsHandler(UpdateUI), pList);
        }
        else
            {
            UpdateUI(this, new MyProgressEvents(msg,
                PercentDone));    
            }
            
        }
     
         private void btnStart_Click(object sender, EventArgs e)
         {
          //启动线程
          Thread t = new Thread(new ParameterizedThreadStart(RunsOnWorkerThread));
          t.IsBackground = true;
          t.Start(input);
         }
     
        //线程执行函数
        private void RunsOnWorkerThread() 
        {
            int i = 0;   
            while(...) //loop      
            {  
              DoSomethingSlow();
              ShowProgress("test",i);
              ++i;
            }
        }
    }

    上面的代码,我们看到什么了?

    啥,直接使用 “InvokeRequired”,不用使用“ToolStripStatusLabel.InvokeRequired”这样的格式!

    对的,这样就可以了。

    当然你也可以使用“StatusStrip.InvokeRequired”这样的形式!

    实例二:

    上面的例子代码可能不太好理解,我们看看微软官方的例子:

    下面的代码示例是一个完整的 Windows 窗体应用程序,它包含一个带有三个按钮和一个文本框的窗体。 第一个按钮演示不安全的跨线程访问,第二个按钮演示使用 Invoke 实现的安全访问,而第三个按钮演示使用 BackgroundWorker 实现的安全访问。

    using System;
    using System.ComponentModel;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace CrossThreadDemo
    {
    	public class Form1 : Form
    	{
    		// This delegate enables asynchronous calls for setting
    		// the text property on a TextBox control.
    		delegate void SetTextCallback(string text);
    
    		// This thread is used to demonstrate both thread-safe and
    		// unsafe ways to call a Windows Forms control.
    		private Thread demoThread = null;
    
    		// This BackgroundWorker is used to demonstrate the 
    		// preferred way of performing asynchronous operations.
    		private BackgroundWorker backgroundWorker1;
    
    		private TextBox textBox1;
    		private Button setTextUnsafeBtn;
    		private Button setTextSafeBtn;
    		private Button setTextBackgroundWorkerBtn;
    
    		private System.ComponentModel.IContainer components = null;
    
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		protected override void Dispose(bool disposing)
    		{
    			if (disposing && (components != null))
    			{
    				components.Dispose();
    			}
    			base.Dispose(disposing);
    		}
    
    		// This event handler creates a thread that calls a 
    		// Windows Forms control in an unsafe way.
    		private void setTextUnsafeBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.demoThread = 
    				new Thread(new ThreadStart(this.ThreadProcUnsafe));
    
    			this.demoThread.Start();
    		}
    
    		// This method is executed on the worker thread and makes
    		// an unsafe call on the TextBox control.
    		private void ThreadProcUnsafe()
    		{
    			this.textBox1.Text = "This text was set unsafely.";
    		}
    
    		// This event handler creates a thread that calls a 
    		// Windows Forms control in a thread-safe way.
    		private void setTextSafeBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.demoThread = 
    				new Thread(new ThreadStart(this.ThreadProcSafe));
    
    			this.demoThread.Start();
    		}
    
    		// This method is executed on the worker thread and makes
    		// a thread-safe call on the TextBox control.
    		private void ThreadProcSafe()
    		{
    			this.SetText("This text was set safely.");
    		}
    
    		// This method demonstrates a pattern for making thread-safe
    		// calls on a Windows Forms control. 
    		//
    		// If the calling thread is different from the thread that
    		// created the TextBox control, this method creates a
    		// SetTextCallback and calls itself asynchronously using the
    		// Invoke method.
    		//
    		// If the calling thread is the same as the thread that created
    		// the TextBox control, the Text property is set directly. 
    
    		private void SetText(string text)
    		{
    			// InvokeRequired required compares the thread ID of the
    			// calling thread to the thread ID of the creating thread.
    			// If these threads are different, it returns true.
    			if (this.textBox1.InvokeRequired)
    			{	
    				SetTextCallback d = new SetTextCallback(SetText);
    				this.Invoke(d, new object[] { text });
    			}
    			else
    			{
    				this.textBox1.Text = text;
    			}
    		}
    
    		// This event handler starts the form's 
    		// BackgroundWorker by calling RunWorkerAsync.
    		//
    		// The Text property of the TextBox control is set
    		// when the BackgroundWorker raises the RunWorkerCompleted
    		// event.
    		private void setTextBackgroundWorkerBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.backgroundWorker1.RunWorkerAsync();
    		}
    		
    		// This event handler sets the Text property of the TextBox
    		// control. It is called on the thread that created the 
    		// TextBox control, so the call is thread-safe.
    		//
    		// BackgroundWorker is the preferred way to perform asynchronous
    		// operations.
    
    		private void backgroundWorker1_RunWorkerCompleted(
    			object sender, 
    			RunWorkerCompletedEventArgs e)
    		{
    			this.textBox1.Text = 
    				"This text was set safely by BackgroundWorker.";
    		}
    
    		#region Windows Form Designer generated code
    
    		private void InitializeComponent()
    		{
    			this.textBox1 = new System.Windows.Forms.TextBox();
    			this.setTextUnsafeBtn = new System.Windows.Forms.Button();
    			this.setTextSafeBtn = new System.Windows.Forms.Button();
    			this.setTextBackgroundWorkerBtn = new System.Windows.Forms.Button();
    			this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
    			this.SuspendLayout();
    			// 
    			// textBox1
    			// 
    			this.textBox1.Location = new System.Drawing.Point(12, 12);
    			this.textBox1.Name = "textBox1";
    			this.textBox1.Size = new System.Drawing.Size(240, 20);
    			this.textBox1.TabIndex = 0;
    			// 
    			// setTextUnsafeBtn
    			// 
    			this.setTextUnsafeBtn.Location = new System.Drawing.Point(15, 55);
    			this.setTextUnsafeBtn.Name = "setTextUnsafeBtn";
    			this.setTextUnsafeBtn.TabIndex = 1;
    			this.setTextUnsafeBtn.Text = "Unsafe Call";
    			this.setTextUnsafeBtn.Click += new System.EventHandler(this.setTextUnsafeBtn_Click);
    			// 
    			// setTextSafeBtn
    			// 
    			this.setTextSafeBtn.Location = new System.Drawing.Point(96, 55);
    			this.setTextSafeBtn.Name = "setTextSafeBtn";
    			this.setTextSafeBtn.TabIndex = 2;
    			this.setTextSafeBtn.Text = "Safe Call";
    			this.setTextSafeBtn.Click += new System.EventHandler(this.setTextSafeBtn_Click);
    			// 
    			// setTextBackgroundWorkerBtn
    			// 
    			this.setTextBackgroundWorkerBtn.Location = new System.Drawing.Point(177, 55);
    			this.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn";
    			this.setTextBackgroundWorkerBtn.TabIndex = 3;
    			this.setTextBackgroundWorkerBtn.Text = "Safe BW Call";
    			this.setTextBackgroundWorkerBtn.Click += new System.EventHandler(this.setTextBackgroundWorkerBtn_Click);
    			// 
    			// backgroundWorker1
    			// 
    			this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
    			// 
    			// Form1
    			// 
    			this.ClientSize = new System.Drawing.Size(268, 96);
    			this.Controls.Add(this.setTextBackgroundWorkerBtn);
    			this.Controls.Add(this.setTextSafeBtn);
    			this.Controls.Add(this.setTextUnsafeBtn);
    			this.Controls.Add(this.textBox1);
    			this.Name = "Form1";
    			this.Text = "Form1";
    			this.ResumeLayout(false);
    			this.PerformLayout();
    
    		}
    
    		#endregion
    
    
    		[STAThread]
    		static void Main()
    		{
    			Application.EnableVisualStyles();
    			Application.Run(new Form1());
    		}
    
    	}
    }
    


    相关参考:

    如何:对 Windows 窗体控件进行线程安全调用

    InvokeRequired and ToolStripStatusLabel

    展开全文
  • 以下代码为正确实现。 this.statusStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow... this.toolStripStatusLabel1.Alignment = System.Windows.Forms.ToolStripIte...

    以下代码为正确实现。

    this.statusStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
                this.toolStripStatusLabel1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
                this.toolStripStatusLabel1.Text = "xxxx © 2019-"+System.DateTime.Today.Year.ToString()+" 信息中心 设计开发";

    添加转载:转帖:https://blog.csdn.net/cdhql/article/details/6119774

    [C#]解决statusStrip控件上的项目不能靠右对齐的问题

    在c#中用到了状态栏控件StatusStrip,但当我想把StatusStrip上某个StatusLabel靠右对齐时出了问题。  

    按照MSDN中的办法,是设置ToolStripStatusLabel的Alignment属性为Right。不过我在设计界面的属性窗口中找不到Alignment。

    就算加入代码toolStripStatusLabel2.Alignment = ToolStripItemAlignment.Right; 也还是没什么效果。

     

    后来我找到两种方法解决这个问题:

    方法一:

    在状态栏所有项目(StatusLabel、ProgressBar、DropDownButton等)前添加一个空白的StatusLabel (Text属性为空),并将其Spring属性设为True。

    Spring属性的作用是设置该项是否填满剩余空间,设为True以后,当程序运行时后面的项就都挤到右边,实现靠右对齐了。

    如果更进一步,需要一部分项靠左,一部分靠右,那就在两部分中间插入空白StatusLabel,同时设其Spring属性为True。

    这种方法比较简单,不用手工添加代码。首选!

     

    方法二:

    这个方法是我无意中发现的。

    设置StatusStrip控件的LayoutStyle属性为HorizontalStackWithOverflow 或 StackWithOverflow。

    然后在代码中修改状态栏上某项的Alignment为Right,这次就有靠右的效果了。

    例如:            this.toolStripStatusLabel1.Alignment = ToolStripItemAlignment.Right;

    注意如果是多个项,那靠左对齐的从左往右排列,靠右对齐的从右往左排列。

     

    问题是基本解决了,只是我还是不知道为什么在属性窗口里ToolStripStatusLabel没有Alignment属性。从网上搜集的帖子看,好像其他人都没这个问题啊?

    有谁知道的话告诉我。对了,我用的是VS2005 版本8.0.50727.42。

    以下转自:https://www.cnblogs.com/xiaowie/p/8624387.html

    态栏用于显示用户状态的简短信息。

     

    StatusStrip控件是由system.windows.forms.statusStrip类提供,作用是在应用程序中标识对话框底部的一栏,通常用于显示应用程序当前状态的简短信息。

     

    在StatusStrip中可以使用toolstrip中介绍的控件中的三个----Toolstripdropdownbutton、toolstripprogressbar、toolstripSplitbutton

     

    还有一个控件就是StatusStrip专用的,即StatusStripStatuslabel,作用就是使用文本和图像用户显示应用程序当前状态的信息。

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    namespace StatusStrip状态栏控件

    {

        public partial class Form1 : Form

        {

            public Form1()

            {

                InitializeComponent();

            }

     

            private void Form1_Load(object sender, EventArgs e)

            {

                toolStripStatusLabel1.Text = DateTime.Now.ToString();

            }

     

            private void timer1_Tick(object sender, EventArgs e)

            {

                toolStripStatusLabel1.Text = DateTime.Now.ToString();

            }

            //鼠标点击事件

            private void textBox1_Click(object sender, EventArgs e)

            {

                //获取当前行第一个字符所在的索引值

                int index = textBox1.GetFirstCharIndexOfCurrentLine();

     

                //计算行号

                int line = textBox1.GetFirstCharIndexFromLine(index);

     

                //计算列数

     

                int column = textBox1.SelectionStart - index + 1;

                //如 textbox索引为 10 11 12 13 14 15 16  比如鼠标选择的是16 怎么计算是多少列呢

                //那index=10  column=selectionstart(当前选择起点16)-index(第一个索引值)+1=第7列

     

                toolStripStatusLabel3.Text = "第"+line+"行,第"+column+"列";

            }

            //键盘弹起事件

            private void textBox1_KeyUp(object sender, KeyEventArgs e)

            {

                //获取当前行第一个字符所在的索引值

                int index = textBox1.GetFirstCharIndexOfCurrentLine();

     

                //计算行号

                int line = textBox1.GetFirstCharIndexFromLine(index);

     

                //计算列数

     

                int column = textBox1.SelectionStart - index + 1;

                //如 textbox索引为 10 11 12 13 14 15 16  比如鼠标选择的是16 怎么计算是多少列呢

                //那index=10  column=selectionstart(当前选择起点16)-index(第一个索引值)+1=第7列

     

                toolStripStatusLabel3.Text = "第" + line+1 + "行" "," "第" + column + "列";

            }

      

     

    展开全文
  • C#添加toolstripstatuslabel

    千次阅读 2017-07-20 11:14:02
    1 在工具箱中添加statusStrip1 2 选中statusStrip1,右键 编辑项,可以添加toolstripstatuslabel、ProgressBar...splitButton、DropdownButtono

    1 在工具箱中添加statusStrip1

    2 选中statusStrip1,右键 编辑项,可以添加toolstripstatuslabel、ProgressBar...splitButton、DropdownButtono





    展开全文
  • 方法很简单:将其Spring属性设为True,Spring属性的作用是设置该项是否填满剩余空间。

    方法很简单:将其Spring属性设为True,Spring属性的作用是设置该项是否填满剩余空间。

    展开全文
  • MSDN :spring属性获取或设置一个值,该值指示在调整窗体大小时, ToolStripStatusLabel是否自动填充StatusStrip上的可用空间 可使得ToolStrip上的label控件在其余部分居中显示 ...
  • vs2010 c# toolStripStatusLabel1显示tooltiptext的方法 程序症状: 在toolStripStatusLabel1(状态栏上的标签)的tooltiptext设置了要显示的文件,运行程序发现并不能显示tooltiptext设置的文本。 解决办法: 在...
  • 设置ToolStripStatusLabel的Text属性后return,但在界面上该文本内容很快就消失。代码: ``` private void setTsslReStatus(string text, Color color) { tsslReStatus.Text = text; tsslReStatus....
  • Form直接访问toolStripStatusLabel的属性,不能范围。报错。后来参考 http://stackoverflow.com/questions/29829936/how-to-update-toolstripstatuslabel-text-from-a-method-passing-all-the-controls-o ...
  • ToolStripStatusLabel设置时间自动更新

    千次阅读 2016-02-22 10:06:46
    在使用委托设置界面上ToolStripStatusLabel类型的控件时间是,发现不能使用自定义的委托方法,在往上查找了一下发现不能使用involve来线程调用。因此只能使用原生委托方法。 //代理public delegate void Set...
  • 在c#中用到了状态栏控件Status...按照MSDN中的办法,是设置ToolStripStatusLabel的Alignment属性为Right。不过我在设计界面的属性窗口中找不到Alignment。 就算加入代码toolStripStatusLabel2.Alignment = ToolStri
  • paip C NET多线程访问 toolStripStatusLabel
  • C#statusStrip简单设置toolStripStatusLabel

    万次阅读 2014-04-14 08:04:20
    属性: 如果不想 toolStripStatusLabel 随着字符串大小改动 Size 的话 设置为 false ,然后在 Size 属性中设置 其宽度   TextAlign 属性: 设置Text 文本怎么显示,九种方式: 左上,中上,右上 左,中,右 左下,中...
  • 在学习过程中,发现了三种方法可以调整StatusStrip控件中ToolStripStatusLabel的位置,具体如下: 方法1: 设置ToolStripStatusLabel的padding属性,通过改变第一个和第三个参数值可以调整其左右位置。 方法2...
  • toolstripstatuslabel 右对齐

    千次阅读 2012-05-15 18:22:48
    在代码中设置toolstripstatuslabel 的属性Alignment 为 System.Windows.Forms.ToolStripItemAlignment.Right
  • paip.C#.NET多线程访问 toolStripStatusLabel

    千次阅读 2013-04-17 16:34:59
    paip.C#.NET多线程访问 toolStripStatusLabel 作者Attilax , EMAIL:1466519819@qq.com toolStripStatusLabel控件比较特殊,无法定义invoke来线程调用。。只好使用原生委托..代码稍微多一些.. ...
  • 在c#中用到了状态栏控件...按照MSDN中的办法,是设置ToolStripStatusLabel的Alignment属性为Right。不过我在设计界面的属性窗口中找不到Alignment。 就算加入代码toolStripStatusLabel2.Alignment = ToolStripIte
  • C#里面,子窗口关闭以后,刷新一个父窗口的控件的属性,怎么办 2011-10-25 16:24 提问者: 52104 | 浏览次数:731次 ...子窗口关闭以后,刷新父窗口的toolStripStatusLabel1的Text属性,怎么办 我来帮他解答
  • 今天做项目时碰到个问题,就是toolStripStatusLabel文本不更新的问题,代码如下 toolStripStatusLabel1.Text = "开始"; …… …… toolStripStatusLabel1.Text = "结束"; 但运行时只有“结束”显示出来了,...
  • statusStrip1.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;toolStripStatusLabel1.Alignment = ToolStripItemAlignment.Right;  
  •  paip.C#.NET多线程拜访 toolStripStatusLabel VC421  作者Attilax , EMAIL:1466519819@qq.com  toolStripStatusLabel件控较比特别,法无定义invoke来线程用调。。  原以为只好应用原生委托..代...
  • paip.C#.NET多线程访问 toolStripStatusLabel VC421 作者Attilax , EMAIL:1466519819@qq.com toolStripStatusLabel控件比较特殊,无法定义invoke来线程调用。。 原以为只好使用原生委托..代码...
  • 关于toolStripStatusLabel1

    2015-12-18 12:39:36
    Form1中 Form2 Form2 = new Form2(); Form2.Owner = this; Form2.Show(); ...Form1.toolStripStatusLabel3.Text = "123";...大神帮忙看下,该怎么改,在Form中点button,Form1中的toolStripStatusLabel3显示
  • 关于toolStripStatusLabel2

    2015-12-18 14:07:13
    toolStripStatusLabel1.Text = "时间: " + DateTime.Now.ToString(); } Form3中 public void button1_Click(object sender, EventArgs e) { Form1.toolStripStatusLabel2.Text = "XXXXXXX"; //这里有...
  • winForm程序,我的窗体上有个statusStrip控件,里面加了3个toolstripstatusLabel1,toolstripstatusLabel12,toolstripstatusLabel13,我想让鼠标停在toolstripstatusLabel2上时才显示内容 调试时代码下面有红浪线...
  • FROM中有“转换”(Name:btnConvert)、“写入”(Name:button1)两个按钮控件,底部有ToolStripStatusLabel(Name:stpbSM)、ToolStripProgressBar(Name:stpbJD) [size=16px]我想实现当点击“转换”按钮后出现...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,072
精华内容 428
关键字:

toolstripstatuslabel