使用ObservableCollection中的活动任务数更新文本块
本文关键字:更新 文本 任务 活动 ObservableCollection 使用 | 更新日期: 2023-09-27 17:58:15
我正在尝试创建一个状态窗口,向用户显示当前有多少任务正在运行。每个任务都被添加到ObservableCollection中,我在窗口XAML中设置了绑定路径,但框不会更新。我已经广泛搜索了一个关于如何实现这一点的好的工作示例或教程,但我什么都找不到。我做错了什么?顺便说一句,这是一个连接到我们办公室的每个Cisco交换机并下载配置文件的程序。
窗口XAML:
<Window x:Class="BackupCiscoConfigs.ProcessRunning"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:BackupCiscoConfigs"
Title="ProcessRunning" Height="300" Width="300"
Closed="Window_Closed" ResizeMode="CanMinimize">
<Grid>
<Button Content="Run" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="btnRun" VerticalAlignment="Bottom" Width="75" Click="btnRun_Click" />
<TextBlock Width="200" Height="85" Margin="35,80,43,65" Text="{Binding Mode=OneWay, Path=d1.results.Count}"></TextBlock>
</Grid>
</Window>
窗口代码隐藏:
namespace BackupCiscoConfigs
{
/// <summary>
/// Interaction logic for ProcessRunning.xaml
/// </summary>
public partial class ProcessRunning : Window
{
private MainWindow m_parent;
private Configuration currentConfig;
public DeviceInterface di;
public ProcessRunning(MainWindow parent)
{
currentConfig = Configuration.loadConfig();
m_parent = parent;
InitializeComponent();
}
private void btnRun_Click(object sender, RoutedEventArgs e)
{
List<Device> devices = currentConfig.devices;
di = new DeviceInterface(currentConfig.tftpIP,
currentConfig.tftpDIR, currentConfig.cmd);
di.RunCommands(devices);
}
}
}
生成任务的类:
namespace BackupCiscoConfigs
{
public class DeviceInterface
{
private string tftpIP;
private string tftpDIR;
private string command;
private string dirDate;
public ObservableCollection<Task> results { get; set; }
public DeviceInterface(string tftpIP, string tftpDIR, string cmd)
{
this.tftpIP = tftpIP;
this.tftpDIR = tftpDIR;
this.command = cmd;
dirDate = DateTimeOffset.Now.ToString("MM.dd.yyyy.HH.mm.ss");
Directory.CreateDirectory(tftpDIR + dirDate);
}
public void RunCommands(List<Device> devices)
{
results = new ObservableCollection<Task>();
foreach (Device d in devices)
{
Device d1 = d;
d1.command = command + " tftp://" + tftpIP + "/" + dirDate + "/" + d1.ip + ".cfg";
results.Add(Task<string>.Factory.StartNew(() => d1.BackupDevice()));
}
string res = "";
foreach (Task<string> t in results)
{
string message = t.Result + "'n";
res += message;
}
MessageBoxResult msg = MessageBox.Show(res);
}
}
}
<Window x:Class="BackupCiscoConfigs.ProcessRunning"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:BackupCiscoConfigs"
Title="ProcessRunning" Height="300" Width="300"
Closed="Window_Closed" ResizeMode="CanMinimize">
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<Button Content="Run" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="btnRun" VerticalAlignment="Bottom" Width="75" Click="btnRun_Click" />
<TextBlock Width="200" Height="85" Margin="35,80,43,65" Text="{Binding Mode=OneWay, Path=Results.Count}"></TextBlock>
</Grid>
</Window>
窗口代码隐藏:
namespace BackupCiscoConfigs
{
/// <summary>
/// Interaction logic for ProcessRunning.xaml
/// </summary>
public partial class ProcessRunning : Window, INotifyPropertyChanged
{
private MainWindow m_parent;
private Configuration currentConfig;
private DeviceInterface di;
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private ObservableCollection<Task> _results;
public ObservableCollection<Task> Results
get
{
return _results;
}
set
{
_results= value;
NotifyPropertyChanged("results");
}
public ProcessRunning(MainWindow parent)
{
currentConfig = Configuration.loadConfig();
m_parent = parent;
InitializeComponent();
}
private void btnRun_Click(object sender, RoutedEventArgs e)
{
List<Device> devices = currentConfig.devices;
di = new DeviceInterface(currentConfig.tftpIP,
currentConfig.tftpDIR, currentConfig.cmd);
di.RunCommands(devices);
Results = di.results;
}
}
}
我能立即看到的两个问题:
- 我看不出你在哪里为这个工作路径设置
DataContext
:Path=d1.results.Count
- 您正在更新
results
属性,但没有实现INotifyPropertyChanged
,这意味着WPF永远不会知道您已将新的ObservableCollection
挂接到结果中