2017-09-14 204 views
0

就像标题所说,我试图通知属性更改,方法RaisePropertyChanged被调用coorectly,但PropertyChanged始终为空。c#:PropertyChanged始终为空

在这里,缩短类:

public class BluetoothManager : INotifyPropertyChanged { 

    private string selectedBluetoothResult; 

    private List<string> foundDevices = new List<string>(5); 
    public List<DeviceInformation> penDevices = new List<DeviceInformation>(); 
    private GattCharacteristic TxCharacteristic; 

    public string SelectedBluetoothResult { 
     get { 
      return selectedBluetoothResult; 
     } 
     set { 
      selectedBluetoothResult = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public List<string> FoundDevices { 
     get 
     { 
      return foundDevices; 
     } 
     set 
     {    
      foundDevices = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public BluetoothManager() { 
     StartScanWatcher(); 
    } 

    public void StartScanWatcher() { 
     Debug.WriteLine("Starting device watcher..."); 

     String query = ""; 
     //query for Bluetooth LE devices 
     query += "System.Devices.DevObjectType:=5 AND System.Devices.Aep.ProtocolId:=\"{BB7BB05E-5972-42B5-94FC-76EAA7084D49}\""; 
     //query for devices with controllers' name 
     query += " AND (System.ItemNameDisplay:=\"" + DeviceName + "\")"; 

     var deviceWatcher = DeviceInformation.CreateWatcher(query); //, requestedProperties, DeviceInformationKind.AssociationEndpoint); 
     deviceWatcher.Added += DeviceWatcher_OnAdded; 
     deviceWatcher.EnumerationCompleted += DeviceWatcher_OnEnumComplete; 
     deviceWatcher.Removed += DeviceWatcher_Removed; 
     deviceWatcher.Stopped += DeviceWatcher_Stopped; 
     deviceWatcher.Updated += DeviceWatcher_Updated; 

     deviceWatcher.Start(); 
     Debug.WriteLine(" StartScanWatcher end"); 
    } 

    private void DeviceWatcher_OnAdded(DeviceWatcher sender, DeviceInformation deviceInfo) { 
     Debug.WriteLine(" DeviceWatcher_OnAdded Start"); 
     lock (foundDevices) { 
      if (foundDevices.Contains(deviceInfo.Id)) { 
       return; 
      } 
      foundDevices.Add(deviceInfo.Id); 
      RaisePropertyChanged("FoundDevices"); 

     } 

     Debug.WriteLine($"[{deviceInfo.Name}] DeviceWatcher_OnAdded..."); 

     if (SelectedBluetoothResult == null) 
     { 
      SelectedBluetoothResult = deviceInfo.Id; 
     } 

    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void RaisePropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     Debug.WriteLine("<<<<<<<<<<<<< BluetoothManager, PropertyChanging: " + propertyName); 
     if (PropertyChanged == null) { 
      Debug.WriteLine("============ BluetoothManager, PropertyChanged == null, " + propertyName); 
      return; 
     } 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     Debug.WriteLine(">>>>>>>>>>>>> BluetoothManager, PropertyChanged: " + propertyName); 
    } 
} 

}

在这里,在XAML文件中的绑定:

<ListView ItemsSource="{Binding BluetoothManager.FoundDevices}" SelectedItem="{Binding BluetoothManager.SelectedBluetoothResult}"> 
          <ListView.Resources> 
           <DataTemplate x:Key="BluetoothDeviceTemplate"> 
            <TextBlock Text="{Binding Path=Sap}"/> 
           </DataTemplate> 
          </ListView.Resources> 
</ListView> 

结合似乎正常工作。

请注意,PropertyChanged始终为null的类不是DataContext和XAML文件。这是否意味着我必须对PropertyChange通知进行不同的处理?

在此先感谢。

编辑: 完整MainWindowViewModel:

public class MainWindowViewModel : INotifyPropertyChanged { 

    private ObservableCollection<BookGame> _booksToDisplay = new ObservableCollection<BookGame>(); 
    private ObservableCollection<BookGame> _games = new ObservableCollection<BookGame>(); 
    private string _url; 
    private int[] _newBooksMID; 
    private int[] _oldBooksMID; 
    private Dictionary<int, int> _newBooksVersionNumbers; 
    private Dictionary<int, int> _oldBooksVersionNumbers; 
    private Dictionary<int, int> _allVersionNumbers; 
    private List<BookGame> _booksToAdd; 
    private long _downloadSpeed; 
    private bool _isDownloading = true; 
    private bool _toggleLastSearchKeyWasReturn = false; 

    string _volumeLabel = ""; 
    FileInfo[] _filesTxt = { }; 
    FileInfo[] _filesAll = { }; 
    private string _folderPath = ""; 
    private string _driveName = null; 
    List<BookGame> _allGames; 
    List<BookGame> _allBooks; 
    List<MP3> _allMP3; 
    long lengthAllBooks = 0; 
    long lengthAllGames = 0; 
    int _percentDownloaded = 100; 
    private long _amountBytesToDownload; 
    private long _amountBytesDownloaded; 
    private long _amountMBytesToDownload; 
    private long _amountMBytesDownloaded; 
    private int _downloadTime; 
    //private bool _isDownloadAborted; 
    ServerCommi serverComm; 

    public BluetoothManager BluetoothManager { get; set; } 

    public MainWindowViewModel() { 

     DownloadTime = 0; 
     AmountBytesToDownload = 0; 
     AmountBytesDownloaded = 0; 

     DriveInfo drive = null; 
     foreach (DriveInfo driveInfo in DriveInfo.GetDrives()) { 
      if (driveInfo.IsReady && driveInfo.VolumeLabel == _volumeLabel) { 
       drive = driveInfo; 
       _driveName = drive.Name; 
       _folderPath = _driveName + _folderPath; 
      } 
     } 


     DirectoryInfo di = new DirectoryInfo(_folderPath); 
     if (di.Exists) 
     { 
      _filesTxt = di.GetFiles("*.txt"); 
      FilesAll = di.GetFiles("*.*"); 

      foreach (FileInfo file in _filesTxt) 
      { 
       try 
       { 
        Convert.ToInt32(file.Name.Split('_')[0]); 
        AddBookGameToList(file); 

       } 
       catch (Exception e) 
       { 
       } 
      } 
     } 


     SearchResults = new ObservableCollection<ResultItem>(); 

     MenuCommand = new RelayCommand(o => { 
      Debug.WriteLine("Menu Command " + o); 
      SwitchBooks(o); 
     }); 
     SearchReturnKeyCommand = new RelayCommand(o => { 
      Debug.WriteLine("00000000000000000000000000000000 SearchReturnKeyCommand " + o); 
      SearchActivated(); 
     }); 
     BrowserCommand = new RelayCommand(o => { 
      Debug.WriteLine("Browser Command main" + o); 
      CallBrowser(""); 
     }); 

     DeleteCommand = new RelayCommand(o => { 
      Debug.WriteLine("Delete Command main" + o); 

     }); 
     ToggleDownloadsCommand = new RelayCommand(o => { 

      Debug.WriteLine(" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| "); 

      Debug.WriteLine(" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| "); 
      Debug.WriteLine("ToggleDownloadsCommand Command main" + o); 
      ToggleDownloads(); 
     }); 


     _viewModelMusic = new ViewModelMusic(_driveName); 
     AllGames = Games.ToList<BookGame>(); 
     AllBooks = BooksToDisplay.ToList<BookGame>(); 
     AllMP3 = _viewModelMusic.Mp3s.ToList<MP3>(); 

     long lengthAllMP3 = 0; 
     foreach (MP3 mp3 in AllMP3) { 
      lengthAllMP3 += mp3.LengthValue; 
     } 

     _viewModelBooks = new ViewModelBooks(BooksToDisplay); 
     _viewModelGames = new ViewModelGames(Games); 
     _viewModelFiles = new ViewModelFiles(FilesAll); 
     _viewModelLumi = new ViewModelLumi(drive, lengthAllBooks, lengthAllGames, lengthAllMP3); 

     _viewModelOverview = new ViewModelOverview(AllBooks, AllGames, AllMP3); 
     _screens[0] = _viewModelOverview; 
     _screens[1] = _viewModelBooks; 
     _screens[2] = _viewModelGames; 
     _screens[3] = _viewModelMusic; 
     _screens[4] = _viewModelFiles; 
     _screens[5] = _viewModelVideos; 
     _screens[6] = _viewModelAdults; 
     _screens[7] = _viewModelLumi; 

     SearchText = ""; 
     SelectedItem = _viewModelBooks; 

     Debug.WriteLine("CALLING ServerCommi! Ring, ring!"); 
     serverComm = new ServerCommi(this); 
     //serverComm.DownloadBooksAsync(); 

     BluetoothManager = new BluetoothManager(); 
    } 

    private void ToggleDownloads() { 
     IsDownloading = !IsDownloading; 
     serverComm.ToggleDownloads(IsDownloading); 
     _viewModelBooks.ToggleDownloads(IsDownloading); 
    } 

    internal void DownloadStateChange(int mid, int newState) { 
     _viewModelBooks.DownloadStateChange(mid, newState); 
    } 

    // params bool[] isDownload : varargs 
    // returns the mid 
    public int AddBookGameToList(FileInfo file, bool isDownload = false) { 

     BookGame bg = new BookGame(file); 
     if (isDownload) { 
      bg.DownloadState = 2; 
      if (bg.Mid == serverComm.DownloadingMID) { 
       bg.DownloadState = 1; 
      } 
     }  

     if (bg.Group.StartsWith("B")) { 
      bg.Group = "Bücher"; 
     } 

     switch (bg.Group) { 
      case "Bücher": 
       if (isDownload) { 
        BooksToDisplay.Insert(0, bg); 
       } else { 
        BooksToDisplay.Add(bg); 
       } 
       lengthAllBooks += bg.LengthValue; 
       break; 
      case "Spiele": 
       Games.Add(bg); 
       lengthAllGames += bg.LengthValue; 
       break; 
      default: 
       Debug.WriteLine("Default: " + bg.Title); 
       break; 
     } 

     return bg.Mid; 
    } 

    private void CallBrowser(string url) { 
     Debug.WriteLine("Url: " + Url); 
     try { 
      System.Diagnostics.Process.Start(Url); 
     } catch (System.ComponentModel.Win32Exception noBrowser) { 
      if (noBrowser.ErrorCode == -2147467259) 
       MessageBox.Show(noBrowser.Message); 
     } catch (System.Exception other) { 
      MessageBox.Show(other.Message); 
     } 
    } 


    string _searchText; 
    public string SearchText { 
     get { 
      return _searchText; 
     } 
     set { 
      Debug.WriteLine("SearchText Value= " + value); 
      if (!_toggleLastSearchKeyWasReturn) { 

       _searchText = value; 
       SearchResults.Clear(); 

       List<ResultItem> _allBooksRI = new List<ResultItem>(); 
       List<ResultItem> _allBooksHelperList = _allBooks.ToList<ResultItem>(); 
       List<ResultItem> _allGamesHelperList = _allGames.ToList<ResultItem>(); 
       List<ResultItem> _allMP3HelperList = _allMP3.ToList<ResultItem>(); 

       if (SelectedItem != null && SelectedItem.Equals(_viewModelGames)) { 
        AddAllResultItemsIf(SearchResults, _allGamesHelperList, _searchText); 
        AddAllResultItemsIf(SearchResults, _allBooksHelperList, _searchText); 
        AddAllResultItemsIf(SearchResults, _allMP3HelperList, _searchText); 
        Debug.WriteLine("===================================== Games - " + SearchResults); 
        Debug.WriteLine("SelectedItem - " + SelectedItem); 
       } else if (SelectedItem != null && SelectedItem.Equals(_viewModelMusic)) { 
        AddAllResultItemsIf(SearchResults, _allMP3HelperList, _searchText); 
        AddAllResultItemsIf(SearchResults, _allGamesHelperList, _searchText); 
        AddAllResultItemsIf(SearchResults, _allBooksHelperList, _searchText); 
        Debug.WriteLine("====================================== Music " + SearchResults); 
        Debug.WriteLine("SelectedItem - " + SelectedItem); 
       } else { 
        AddAllResultItemsIf(SearchResults, _allBooksHelperList, _searchText); 
        AddAllResultItemsIf(SearchResults, _allGamesHelperList, _searchText); 
        AddAllResultItemsIf(SearchResults, _allMP3HelperList, _searchText); 

        Debug.WriteLine("====================================== Books " + SearchResults); 
       } 

       if (SearchResults.Count == 0) { 
        SearchResults.Add(new ErrorResultItem("Error", "Nichts passendes gefunden.")); 
       } 
      } else { 
       _toggleLastSearchKeyWasReturn = false; 
      } 
     } 
    } 

    private ObservableCollection<ResultItem> AddAllResultItemsIf(ObservableCollection<ResultItem> searchResults, List<ResultItem> toAdd, string searchText) { 
     foreach (ResultItem item in toAdd) { 
      if (item.Title.ToLower().Contains(_searchText.ToLower())) { 
       searchResults.Add(item); 
      }    
     } 
     return searchResults; 
    } 
    public ObservableCollection<ResultItem> SearchResults { 
     get; set; 
    } 
    ResultItem _selectedResult; 
    public ResultItem SelectedResult { 
     get { 
      return _selectedResult; 
     } 
     set { 
      _selectedResult = value; 
      SearchItemSelected(value); 
     } 
    } 

    private void SearchItemSelected(ResultItem value) { 
     switch (value.Group) { 
      case "Bücher": 
       SelectedItem = _viewModelBooks;     
       break; 
      case "Spiele": 
       SelectedItem = _viewModelGames;     
       break; 
      case "Musik": 
       SelectedItem = _viewModelMusic;     
       break; 
      default: 
       Debug.WriteLine("Search Item Selected, jumped to default: " + value); 
       break; 
     } 
     Unmark(Marked); 
     Mark(value); 
    } 

    ResultItem _marked; 
    internal void Mark(ResultItem value) { 
     Marked = value; 
     value.Marked = true; 
    } 
    internal void Unmark(ResultItem value) { 
     Marked = null; 
     if (value != null) { 
      value.Marked = false; 
     } 

    } 
    public ResultItem Marked { 
     get => _marked; 
     set => _marked = value; 
    } 

    private bool _isSearchResult; 
    public bool IsSearchResult { 
     get { 
      return _isSearchResult; 
     } 
     set { 
      _isSearchResult = value; 
      Debug.WriteLine("IsSearchResult= " + value); 
      RaisePropertyChanged(); 
     } 
    } 
    private void SearchActivated() { 
     _toggleLastSearchKeyWasReturn = true; 
     SelectedItem = _viewModelOverview; 
     IsSearchResult = true; 

    } 

    private object _selectedItem; 
    public object SelectedItem { 
     get { 
      return _selectedItem; 
     } 
     set { 
      _selectedItem = value; 
      Debug.WriteLine("SELECTED_ITEM SETTER: " + value); 
      Unmark(Marked); 
      IsSearchResult = false; 
      if (SearchText != null) { 
      SearchText = SearchText; 
      } 

      RaisePropertyChanged(); 
     } 
    } 

    ViewModelOverview _viewModelOverview; 
    ViewModelBooks _viewModelBooks; 
    ViewModelGames _viewModelGames; 
    ViewModelMusic _viewModelMusic; 
    ViewModelFiles _viewModelFiles; 
    ViewModelVideos _viewModelVideos = new ViewModelVideos(); 
    ViewModelAdults _viewModelAdults = new ViewModelAdults(); 
    ViewModelLumi _viewModelLumi; 

    object[] _screens = new object[8]; 

    public object[] Screens { 
     get { 
      return _screens; 
     } 
    } 


public event PropertyChangedEventHandler PropertyChanged; 
private void RaisePropertyChanged([CallerMemberName] string propertyName = null) { 
    if (PropertyChanged == null) 
     return; 
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
} 


    public ICommand MenuCommand { 
     get; set; 
    } 
    public ICommand SearchReturnKeyCommand { 
     get; set; 
    } 
    public ICommand BrowserCommand { 
     get; set; 
    } 
    public ICommand ToggleDownloadsCommand { 
     get; set; 
    } 


    public RelayCommand DeleteCommand { 
     get; 
     private set; 
    } 
    public List<BookGame> AllGames { 
     get => _allGames; 
     set => _allGames = value; 
    } 
    public List<BookGame> AllBooks { 
     get => _allBooks; 
     set => _allBooks = value; 
    } 
    public List<MP3> AllMP3 { 
     get => _allMP3; 
     set => _allMP3 = value; 
    } 
    public ViewModelBooks ViewModelBooks { 
     get => _viewModelBooks; 
     set => _viewModelBooks = value; 
    } 
    public ObservableCollection<BookGame> BooksToDisplay { 
     get => _booksToDisplay; 
     set => _booksToDisplay = value; 
    } 
    public ObservableCollection<BookGame> Games { 
     get => _games; 
     set => _games = value; 
    } 

    public string Url { 
     get { 
      return _url; 
     } 
     set { 
      _url = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public int[] NewBooksMID { 
     get => _newBooksMID; 
     set => _newBooksMID = value; 
    } 
    public int[] OldBooksMID { 
     get => _oldBooksMID; 
     set => _oldBooksMID = value; 
    } 
    public Dictionary<int, int> NewBooksVersionNumbers { 
     get => _newBooksVersionNumbers; 
     set => _newBooksVersionNumbers = value; 
    } 
    public Dictionary<int, int> OldBooksVersionNumbers { 
     get => _oldBooksVersionNumbers; 
     set => _oldBooksVersionNumbers = value; 
    } 
    public Dictionary<int, int> AllVersionNumbers { 
     get => _allVersionNumbers; 
     set => _allVersionNumbers = value; 
    } 
    public int[] OldBooksMID1 { 
     get => _oldBooksMID; 
     set => _oldBooksMID = value; 
    } 
    public List<BookGame> BooksToAdd { 
     get => _booksToAdd; 
     set => _booksToAdd = value; 
    } 
    public FileInfo[] FilesAll { 
     get => _filesAll; 
     set => _filesAll = value; 
    } 
    public string FolderPath { 
     get => _folderPath; 
     set => _folderPath = value; 
    } 
    public int PercentDownloaded { 
     get { 
      return _percentDownloaded; 
     } 
     set { 
      _percentDownloaded = value; 
      RaisePropertyChanged();    
     } 
    } 

    public long DownloadSpeed { 
     get { 
      return _downloadSpeed; 
     } 
     set { 
      _downloadSpeed = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public long AmountBytesToDownload { 
     get { 
      return _amountBytesToDownload; 
     } 
     set { 
      _amountBytesToDownload = value; 

      Debug.WriteLine("Property Changed: " + "AmountBytesToDownload"); 
      AmountMBytesToDownload = value/1024/1024; 
     } 
    } 
    public long AmountBytesDownloaded { 
     get { 
      return _amountBytesDownloaded; 
     } 
     set { 
      _amountBytesDownloaded = value; 
      AmountMBytesDownloaded = value/1024/1024; 
     } 
    } 

    public int DownloadTime { 
     get { 
      return _downloadTime; 
     } 
     set { 
      _downloadTime = value; 
      RaisePropertyChanged(); 
     } 
    } 
    /* 
    public bool IsDownloadAborted { 
     get { 
      return _isDownloadAborted; 
     } 
     set { 
      _isDownloadAborted = value; 
      RaisePropertyChanged(); 
     } 
    } 
    */ 
    public long AmountMBytesDownloaded { 
     get { 
      return _amountMBytesDownloaded; 
     } 
     set { 
      _amountMBytesDownloaded = value; 
      RaisePropertyChanged(); 
     } 
    } 
    public long AmountMBytesToDownload { 
     get { 
      return _amountMBytesToDownload; 
     } 
     set { 
      _amountMBytesToDownload = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public bool IsDownloading { 
     get { 
      return _isDownloading; 
     } 
     set { 
      _isDownloading = value; 
      RaisePropertyChanged(); 
     } 
    } 

    internal void SwitchBooks(object o) { 
     Debug.WriteLine("SwitchBooksEx " + o); 

     if (o.ToString().Equals("Tessloff.ViewModelBooks")) { 
      ((ViewModelBooks)_screens[0]).SwitchView(); 
      Debug.WriteLine("SwitchBooksIn " + o); 
     } 
    } 
} 


public class CommandViewModel { 
     private MainWindowViewModel _viewmodel; 

     public CommandViewModel(MainWindowViewModel viewmodel) { 

      _viewmodel = viewmodel; 
     Debug.WriteLine("LALALALALA"); 

     MenuCommand = new RelayCommand(o => { 
       Debug.WriteLine("CommandViewModel " + o); 
       _viewmodel.SwitchBooks(o); 
      }); 

     DeleteCommand = new RelayCommand(o => { 
      Debug.WriteLine("Delte Command CVM" + o); 

     }); 
    } 

    public ICommand MenuCommand { 
      get; set; 
     } 
    public ICommand DeleteCommand { 
     get; set; 
    } 
    public string Title { 
      get; 
      private set; 
     } 
} 


    public class RelayCommand : ICommand { 
     #region Fields 

     readonly Action<object> _execute; 
     readonly Predicate<object> _canExecute; 

     #endregion // Fields 

     #region Constructors 

     public RelayCommand(Action<object> execute) 
     : this(execute, null) { 
     } 

     public RelayCommand(Action<object> execute, Predicate<object> canExecute) { 
      if (execute == null) 
       throw new ArgumentNullException("execute"); 

      _execute = execute; 
      _canExecute = canExecute; 
     } 
     #endregion // Constructors 

     #region ICommand Members 

     [DebuggerStepThrough] 
     public bool CanExecute(object parameter) { 
      return _canExecute == null ? true : _canExecute(parameter); 
     } 

     public event EventHandler CanExecuteChanged { 
      add { 
       CommandManager.RequerySuggested += value; 
      } 
      remove { 
       CommandManager.RequerySuggested -= value; 
      } 
     } 

     public void Execute(object parameter) { 
      _execute(parameter); 
     } 

     #endregion // ICommand Members 
    } 



public class ViewModelAdults { 
    public ViewModelAdults() { 
     Title = "Erwachsene"; 
     ImgUrl = "/Resources/Erwachsene.png"; 
    } 

    public string Title { 
     get; set; 
    } 
    public string ImgUrl { 
     get; 
     private set; 
    } 
} 

编辑TL;博士: 为什么所有的 “直接” MainWindowViewModel更新大(如MainWindowViewModel.IsSearchResult),但两者的性质“间接“属性不(MainWindowViewModel.BluetoothManager.SelectedBluetoothResul t)。

+3

'if(PropertyChanged == null)'检查是否有订阅者,而不是'RaisePropertyChanged'方法的参数。 – Sinatr

+1

当您将项目放入列表中时,'FoundDevices'属性不会更改('set')。您应该将'List '更改为'ObservableCollection '。 –

+0

@Sinatr所以我必须添加订阅者?在哪里以及如何?为什么我从来没有这样做过? – murkr

回答

0

List.add()不触发PropertyChange。在添加项目之后,您需要使用ObservableCollection或自己提高PropertyChange。

+0

我这样做不是吗? foundDevices.Add(deviceInfo。ID); RaisePropertyChanged(“FoundDevices”); – murkr

+0

并改为ObservableCollection没有做任何事情。 – murkr

+0

演示如何为Window/Control设置DataContext。你可以尝试设置DataContext = new MainWindowViewModel();在自己的窗口/控制 – Giltanas