无法使计时器更新属性


Drive usage info shows correctly. But when I switch off of the drives the disk usage info is not updated. I can't figure out why. 
<local1:Drives x:Key="drivesUsage" />
<StackPanel
Name="stkDrives"
Grid.Row="3"
Grid.ColumnSpan="2"
DataContext="{StaticResource drivesUsage}"
Orientation="Horizontal">
<Label Margin="10" VerticalAlignment="Center">
C:
</Label>
<TextBox
Name="txbDriveC"
Margin="2"
VerticalAlignment="Center"
Style="{StaticResource txbStyle}"
Text="{Binding DriveC}" />
<Label Margin="15" VerticalAlignment="Center">
D:
</Label>
<TextBox
Name="txbDriveD"
Margin="2"
VerticalAlignment="Center"
Style="{StaticResource txbStyle}"
Text="{Binding DriveD}" />
<Label Margin="15" VerticalAlignment="Center">
I:
</Label>
<TextBox
Name="txbDriveI"
Margin="2"
VerticalAlignment="Center"
Style="{StaticResource txbStyle}"
Text="{Binding DriveI}" />
<Label Margin="15" VerticalAlignment="Center">
H:
</Label>
<TextBox
Name="txbDriveH"
Margin="2"
VerticalAlignment="Center"
Style="{StaticResource txbStyle}"
Text="{Binding DriveH}" />
</StackPanel>
public partial class MainWindow : Window
{
public MainWindow()
{

InitializeComponent();
Timer myTimer = new Timer(1000);
myTimer.Start();
myTimer.Elapsed += new ElapsedEventHandler(timeToCall);
}

private void timeToCall(object sender, ElapsedEventArgs e)
{
DrivesCheck();
}
private void DrivesCheck()
{
Drives d = new Drives();
}
}   
public class Drives : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
private string driveC;
private string driveD;
private string driveI;
private string driveH;
public string DriveC
{
get { return driveC; }
set
{
driveC = value;
OnPropertyChanged(nameof(DriveC));
}
}
public string DriveD
{
get { return driveD; }
set
{
driveD = value;
OnPropertyChanged(nameof(DriveD));
}
}
public string DriveI
{
get { return driveI; }
set
{
driveI = value;
OnPropertyChanged(nameof(DriveI));
}
}
public string DriveH
{
get { return driveH; }
set
{
driveH = value;
OnPropertyChanged(nameof(DriveH));
}
}
private List<Tuple<string, double>> diskUsage()
{
var result = new List<Tuple<string, double>>(4);
DriveInfo[] allDrives = DriveInfo.GetDrives()
.Where(p => p.DriveType == DriveType.Fixed)
.Select(p => p).ToArray();
foreach (DriveInfo d in allDrives)
{
var driveName = d.Name.Substring(0, 2);
if (d.IsReady == true)
{
var freeSpace = Math.Round(d.TotalFreeSpace / Math.Pow(1024, 3));
result.Add(new Tuple<string, double>(driveName, freeSpace));
}
}
return result;
}
public Drives()
{
var result = diskUsage();
int size = result.Count;
switch (size)
{
case 4:
DriveC = result[0].Item2.ToString();
DriveD = result[1].Item2.ToString();
DriveI = result[2].Item2.ToString();
DriveH = result[3].Item2.ToString();
break;
case 3:
DriveC = result[0].Item2.ToString();
DriveD = result[1].Item2.ToString();
DriveI = result[2].Item2.ToString();
DriveH = "0";
break;
case 2:
DriveC = result[0].Item2.ToString();
DriveD = result[1].Item2.ToString();
DriveI = "0";
DriveH = "0";
break;
case 1:
DriveC = result[0].Item2.ToString();
DriveD = "0";
DriveI = "0";
DriveH = "0";
break;
default:
break;
}
}
}

您正在DrivesCheck()方法中创建新的Drives对象。此新对象与您的StackPanel无关。

您可以重新设置StackPanelDataContext

private void DrivesCheck()
{
stkDrives.DataContext = new Drives();
}

还应使用DispatcherTimer来确保访问 UI 线程上的StackPanel

public MainWindow()
{
InitializeComponent();
System.Windows.Threading.DispatcherTimer myTimer = new System.Windows.Threading.DispatcherTimer();
myTimer.Interval = TimeSpan.FromSeconds(1);
myTimer.Start();
myTimer.Tick += timeToCall;
}
private void timeToCall(object sender, EventArgs e)
{
DrivesCheck();
}

或者,您可以通过例如将代码从Drives类的构造函数移动到可以从DrivesCheck()方法调用的公共方法来重构代码:

private void DrivesCheck()
{
Drives d = this.Resources["drivesUsage"] as Drives;
d.Update(); //<-- this method should update the Drive* properties
}

最新更新