c# - 如何根据 TextBoxes 的内容增加 ProgressBar 的值?
问题描述
所以我有 4 个文本框,并且我已经将 ProgressBar 的最大值设置为4
.
ProgressAttr.Maximum = 4;
我想做的是在1
每次填写文本框时增加我的 ProgressBar 值。
我的代码现在看起来像这样:
if (!string.IsNullOrEmpty(Name_txtBox.Text))
{
ProgressAttr.Value += 1;
}
if (!string.IsNullOrEmpty(Serial_TxtBox.Text))
{
ProgressAttr.Value += 1;
}
if (!string.IsNullOrEmpty(Cap_TxtBox.Text))
{
ProgressAttr.Value += 1;
}
if (!string.IsNullOrEmpty(IDprk_TxtBox.Text))
{
ProgressAttr.Value += 1;
}
这不会增加我的 ProgressBar 的值。
我也试过这个:
if (textbox.Text.Length > 0)
{
ProgressAttr.Value += 1;
}
这些都不适合我,我已经尝试了几个小时寻找解决方案。我非常感谢您的帮助,并期待看到你们提出的解决方案!
解决方案
我建议您使用 DataBindings 将 TextBox 的内容与Value
ProgressBar 的属性同步的方法。
类对象可以通知与其实现INotifyPropertyChanged接口的属性值相关的更改。引发其公共PropertyChanged
事件以通知绑定控件数据提供者的属性已更改。
然后将所有绑定的属性更新为新值。
这使您可以将所有逻辑放在一个地方,并且对用户界面(此处为您的表单)的更改不会以任何方式影响数据绑定。
您可以在 UI 中添加或删除控件。绑定过程不会更改或需要跟踪 UI 中发生的更改。
例如,将您ProgressBar.Value
的属性绑定到该ProgressBarController.Value
属性。您使用要包含的 TextBox(或 RichTextBox)控件的实例初始化 ProgressBarController,添加一个 Binding 以链接属性,仅此而已。其余的都是自动发生的。
ProgressBarController pbarController = null;
// Form Constuctor
public SomeForm()
{
InitializeComponent();
// [...]
// These TextBoxes could be child of a Container (e.g., a Panel), so you could
// also get all the child Controls of this Container to build the array
var textBoxes = new[]{ Name_txtBox, Serial_TxtBox, Cap_TxtBox, IDprk_TxtBox}
ProgressAttr.Maximum = textBoxes.Length;
pbarController = new ProgressBarController(textBoxes);
ProgressAttr.DataBindings.Add("Value", pbarController, "Value", false,
DataSourceUpdateMode.OnPropertyChanged);
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
pbarController.Dispose();
base.OnFormClosed(e);
}
在这里,两个 TextBox 在加载表单时已经包含一些文本,因此 ProgressBar 显示了一个进度。如果您删除设计器中的所有文本,那么最初显示的进度当然是0
:
该类ProgressBarController
使用其构造函数中传递的控件数组进行初始化。
► 然后它构建一个Dictionary<TextBoxBase, int>
来跟踪与控件关联的进度值:0
如果其 Text 为空,否则1
。
TextBoxBase所以你也可以使用 RichTextBox 控件。
►TextChanged
这些控件的事件是使用单个处理程序订阅的。该sender
对象将是引发事件的控件。
► 如果/当关联值已更改(控件文本状态确定更改),PropertyChanged
则引发事件并且 DataBinding 通知 ProgressBar 更新其Value
属性。
► 当父窗体关闭时,调用Dispose()
该类的方法取消对TextChanged
事件的订阅。
using System.Runtime.CompilerServices;
private class ProgressBarController : INotifyPropertyChanged, IDisposable
{
public event PropertyChangedEventHandler PropertyChanged;
private Dictionary<TextBoxBase, int> states;
private int m_Value = 0;
public ProgressBarController(params TextBoxBase[] tboxes) {
states = new Dictionary<TextBoxBase, int>();
for (int i = 0; i < tboxes.Length; i++) {
states.Add(tboxes[i], tboxes[i].Text.Length > 0 ? 1 : 0);
tboxes[i].TextChanged += TextChanged;
}
m_Value = states.Values.Sum();
}
public int Value {
get => m_Value;
private set {
if (value != m_Value) {
m_Value = value;
OnPropertyChanged();
}
}
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected void TextChanged(object sender, EventArgs e)
{
var tbx = sender as TextBoxBase;
int state = tbx.Text.Length > 0 ? 1 : 0;
if (states[tbx] != state) {
states[tbx] = state;
Value = states.Values.Sum();
}
}
public void Dispose() {
foreach (var tb in states.Keys) {
tb.TextChanged -= this.TextChanged;
}
}
}
推荐阅读
- javascript - 无法在 ckeditor 中设置未定义的属性“目录”
- html - 尝试在 Angular 5 中使用 get 调用其余 api
- java - Java 注解在 Spring Framework 中的工作原理
- javascript - 未定义的用户 ID
- python - StreamPlayer“之后”函数没有被调用
- windows-installer - 如何在不同的 msi InstallShield 2011 之间共享 INSTALLDIR 值
- python - 如何在不使用 Flask 和 Django 的情况下在核心 Python 中添加 CSS 和 JS 文件?
- laravel - Laravel:如何从具有多态关系雄辩模型的表中轻松获取值?
- telegram - 如何解决带有授权错误的android电报。请重新安装应用程序并使用您的电话号码重新登录。?
- python - 找到漂亮汤的 CSS 选择器