使用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);
        }
    }
}

使用ObservableCollection中的活动任务数更新文本块

<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;
        }
    }
}

我能立即看到的两个问题:

  1. 我看不出你在哪里为这个工作路径设置DataContextPath=d1.results.Count
  2. 您正在更新results属性,但没有实现INotifyPropertyChanged,这意味着WPF永远不会知道您已将新的ObservableCollection挂接到结果中