2017-08-22 1 views
-1
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; 
      } 
     } 
    } 

答えて

2

DrivesCheck()メソッドで新しいDrivesオブジェクトを作成しています。この新しいオブジェクトは、StackPanelに接続していません。

あなたはStackPanelDataContext再設定できます

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

また、あなたはUIスレッド上StackPanelにアクセスしていることを確認するDispatcherTimerを使用する必要があります。

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 
} 
+0

あなたが示唆したように、私はStackPanelのDataContextを再設定しようとしましたが、何とか変更を加えませんでした。クラスからコードを移動するのではなく、この単純なメソッドを使用するほうが好きです。 – LetzerWille

+1

DispatcherTimerの使用を試みます。私の編集を参照してください。 – mm8

関連する問題