英文:
Update progress bar value while processing in WPF
问题
我有一个屏幕,用于通过COM/USB端口检查与多个设备的连接,如下图所示:
链接到图片
当用户点击“检查设备”按钮时,如果检查设备连接完成,好或不好的图标将显示在组合框旁边,并且进度条将根据设备总数更新值。例如,如果有4个设备,那么进度条将在检查后更新为25%、50%、75%、100%。
我尝试使用PropertyChanged来更新值,但似乎不起作用。单击按钮后,进度条可见,但值始终为100。请帮我解决这个问题!
这是我的代码:
XAML 文件:
<ProgressBar x:Name="pgProcessing" Visibility="Collapsed" Minimum="0" Maximum="100" Value="{Binding Percent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
代码后台:
private double _percent;
public double Percent
{
get { return _percent; }
set { _percent = value; OnPropertyChanged("Percent"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void BtnCheck_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
_percent = 0;
this.Percent = _percent;
// 检查第一个设备的连接
// 结束
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent; //50%
// 检查第二个设备的连接
// 结束
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent; //100%
}
我的构造函数:
public HealthCheck()
{
InitializeComponent();
this.DataContext = this;
}
我也在 cs 文件中实现了 INotifyPropertyChanged。
英文:
I have a screen which used to check connection with multiple devices by COM/USB Port as the below picture
https://i.stack.imgur.com/CAjK0.png
When user click button Check Device if checking a device connection is finished, icon good or not good will display next to combobox and progress bar will update value based on total of devices. For example, there are 4 devices then progress bar will update 25%, 50%, 75%, 100% after checking.
I tried to use PropertyChanged to update value but it's seem not working. After clicking button, the progress bar is visible but value is always 100. Please help me with this!
Here is my code:
File xaml:
<ProgressBar x:Name="pgProcessing" Visibility="Collapsed" Minimum="0" Maximum="100" Value ="{Binding Percent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
Code behind:
private double _percent;
public double Percent
{
get { return _percent; }
set { _percent = value; OnPropertyChanged("Percent"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void BtnCheck_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
_percent = 0;
this.Percent = _percent;
// Do check connection 1st device
// End
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent; //50%
// Do check connection 2nd device
// End
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent; //100%
}
My constructor:
public HealthCheck()
{
InitializeComponent();
this.DataContext = this;
}
I also implement INotifyPropertyChanged in the cs file
答案1
得分: 2
代码部分不进行翻译,以下是翻译的内容:
"Seems you are confusing how the Binding works. My recommendation would be to use MVVM pattern and not mix stuff up (if possible). To solve your problem there are two ways. First let the code behind remain code behind. All you need is to assign the Value directly to the progress bar like this:
然而,如果你想使用MVVM,你也可以在代码中调用模型上的属性更改。示例:
public class Model : INotifyPropertyChanged
{
private double _percent;
public double Percent
{
get { return _percent; }
set { _percent = value; OnPropertyChanged("Percent"); }
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
and your *xaml.cs :
public partial class MainWindow : Window
{
readonly Model _model;
public MainWindow()
{
InitializeComponent();
_model = new Model();
DataContext = _model;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
_model.Percent = 0;
await Task.Delay(100);
_model.Percent = 25;
await Task.Delay(100);
_model.Percent = 50;
await Task.Delay(100);
_model.Percent = 75;
await Task.Delay(100);
_model.Percent = 100;
}
}
Regardless, I suggest to implement ICommand/RelayCommand pattern into your ViewModel as well and process button press also within ViewModel."
英文:
Seems you are confusing how the Binding works. My recommendation would be to use MVVM pattern and not mix stuff up (if possible). To solve you problem there are two ways. First let the code behind remain code behind. All you need is to assign the Value directly to the progress bar like this:
private async void Button_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
pgProcessing.Value = 0;
await Task.Delay(100);
pgProcessing.Value = 25;
await Task.Delay(100);
pgProcessing.Value = 50;
await Task.Delay(100);
pgProcessing.Value = 75;
await Task.Delay(100);
pgProcessing.Value = 100;
}
However if you would like to use MVVM, I you can call the property changes on the model via code behind as well. Example :
public class Model : INotifyPropertyChanged
{
private double _percent;
public double Percent
{
get { return _percent; }
set { _percent = value; OnPropertyChanged("Percent"); }
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
and your *xaml.cs :
public partial class MainWindow : Window
{
readonly Model _model;
public MainWindow()
{
InitializeComponent();
_model = new Model();
DataContext = _model;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
_model.Percent = 0;
await Task.Delay(100);
_model.Percent = 25;
await Task.Delay(100);
_model.Percent = 50;
await Task.Delay(100);
_model.Percent = 75;
await Task.Delay(100);
_model.Percent = 100;
}
}
Regardless, I suggest to implement Icommand/relayCommand pattern into your ViewModel as well and proccess button press also within View Model.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论