我正在尝试创建一个状态窗口,向用户显示当前正在运行的任务数。每个任务都被添加到一个ObservableCollection中,我在窗口XAML中设置了绑定路径,但该框没有更新。我已经广泛搜索了一个很好的工作示例或教程如何实现这一点,我找不到任何东西。我究竟做错了什么?这是一个连接到办公室中每个思科交换机的程序,顺便下载配置文件。
窗口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);
}
}
}
答案 0 :(得分: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;
}
}
}
答案 1 :(得分:0)
我可以立即看到两个问题:
DataContext
的位置:Path=d1.results.Count
results
属性,但您没有实施INotifyPropertyChanged
,这意味着WPF永远不会知道您已将新的ObservableCollection
挂钩到结果中。