简体   繁体   中英

c#: PropertyChanged always null

Like the title says, I try to notify a property change, the method RaisePropertyChanged is called coorectly, but PropertyChanged is always null.

Here the shortened class:

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

}

And here the Binding in the XAML file:

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

The binding seems to work properly.

Please note, that the class in which the PropertyChanged is always null is not the DataContext auf the XAML file. Does that mean I have to work differently with the PropertyChange notification?

Thanks in advance.

EDIT: The complete 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;
    }
}

Edit tl;dr: Why do all "direct" properties of MainWindowViewModel update great (like MainWindowViewModel.IsSearchResult), but the two "indirect" properties don't (MainWindowViewModel.BluetoothManager.SelectedBluetoothResul‌​t).

List.add() doesnt trigger PropertyChange. You need to use ObservableCollection or raise PropertyChange yourself after adding item.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM