无法进行计时器更新属性

时间:2017-08-22 10:52:37

标签: c# wpf data-binding timer

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

1 个答案:

答案 0 :(得分:2)

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

您可以重新设置DataContext的{​​{1}}:

StackPanel

您还应该使用private void DrivesCheck() { stkDrives.DataContext = new Drives(); } 来确保您访问UI线程上的DispatcherTimer

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()