0

現在実行中のタスクの数をユーザーに表示するステータス ウィンドウを作成しようとしています。各タスクは 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);
        }
    }
}
4

2 に答える 2

1
<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;
        }
    }
}
于 2013-02-07T15:24:39.633 に答える
0

すぐにわかる 2 つの問題:

  1. DataContextこのパスが機能するように設定している場所がわかりません:Path=d1.results.Count
  2. プロパティを更新resultsしていますが、実装INotifyPropertyChangedしていません。つまり、WPF はObservableCollection結果に新しいものをフックしたことを決して認識しません。
于 2013-02-07T15:25:16.263 に答える