4

I have a dropbox:

<ComboBox Height="23" Name="DriveSelection" Width="120"
                              ItemsSource="{Binding Path=FixedDrives}"
                              DisplayMemberPath="Name"
                              SelectedItem="{Binding Path=DriveSelection_SelectionChanged}"
                              IsSynchronizedWithCurrentItem="True"
                              IsEnabled="{Binding DriveIsEnabled}"
                              SelectedValue="{Binding DriveSelected}"
                              />

with this bindings:

private ObservableCollection<DriveInfo> fixedDrives;
public ObservableCollection<DriveInfo> FixedDrives
{
    get
    {
        if (this.fixedDrives != null)
            return this.fixedDrives;
        this.fixedDrives = new ObservableCollection<DriveInfo>(Enumerable.Where<DriveInfo>((IEnumerable<DriveInfo>)DriveInfo.GetDrives(), (Func<DriveInfo, bool>)(driveInfo => driveInfo.DriveType == DriveType.Fixed)));
        return this.fixedDrives;
    }
}


public DriveInfo DriveSelection_SelectionChanged
{
    get
    {
        return this.driveSelection;
    }
    set
    {
        if (value == this.driveSelection)
            return;
        this.driveSelection = value;
        UpdatePathManager();
        this.OnPropertyChanged("DriveSelection_SelectionChanged");
    }
}
public object DriveSelected
{
    get
    {
        return _driveSelected;
    }
    set
    {
        _driveSelected = value;
        RaisePropertyChanged("DriveSelected");
    }
}

and While doing page initialization:

public PathSelectionPageViewModel(PathSelectionPage _page)
{
    this.page = _page;
    this.root = Path.GetPathRoot(App.Instance.PathManager.InstallRoot).ToUpperInvariant();
    this.DriveSelected = (object)this.root;
    //this.page.DriveSelection.SelectedValue = (object)this.root;
    this.DriveIsEnabled = true
    //this.page.DriveSelection.IsEnabled = true
    this.driveSelection = new DriveInfo(this.root);
}

on the last line: this.driveSelection = new DriveInfo(this.root); I'm geting null reference exception in this line:

private void UpdatePathManager()
{
    string newRoot = this.driveSelection.ToString(); <--- this line
    //string newRoot = this.page.DriveSelection.SelectedValue.ToString();
}

As you can see I was just trying to change reading data straight from View into bindings but I have problems with this. What shoudl be changed in order to fix it?

@Update As I just found: problem is in during processing bindings. Wpf is processing bindings in this order ->

  1. FixedDrives
  2. Selection Changed
  3. DriveIsEnabled
  4. DriveSelected

and processing DriveSelected is firing the `DriveSelection_SelectionChanged" with value = null. and this Is causing the problems.

daniele3004
  • 13,072
  • 12
  • 67
  • 75
szpic
  • 4,346
  • 15
  • 54
  • 85
  • 3
    Stacktrace or it didn't happen – leppie Aug 28 '14 at 11:19
  • 1
    Apparantly `driveSelection` is `null`. So use a debugger to see if you actually get to the point where you think you set it to some value. – Dirk Aug 28 '14 at 11:23
  • Try moving the line this.driveSelection = new DriveInfo(this.root); to the beginning of the constructor, just after this.root = Path.GetPathRoot ... – too Aug 28 '14 at 11:24

2 Answers2

2

The real problem here is that new DriveInfo(this.root) that you assign with this code

this.driveSelection = new DriveInfo(this.root);

is not part of your FixedDevices collection. That results in that null is passed to your property by the WPF-Binding.

After that the check

if (value == this.driveSelection)

in the property DriveSelection_SelectionChanged results in false, cause you have assigned new DriveInfo(this.root) to the variable driveSelection.

The failing check causes that driveSelection gets set to null and then throws the NullReferenceException in UpdatePathManager()

Jehof
  • 34,674
  • 10
  • 123
  • 155
1

Looks like possibly DriveIsEnabled setter (not included in your code) is calling UpdatePathManger(). You should ensure that this.driveSelection is never null by changing the constructor to:

    public PathSelectionPageViewModel(PathSelectionPage _page)
    {
        this.page = _page;
        this.root = Path.GetPathRoot(App.Instance.PathManager.InstallRoot).ToUpperInvariant();
        this.driveSelection = new DriveInfo(this.root);
        this.DriveSelected = (object)this.root;
        //this.page.DriveSelection.SelectedValue = (object)this.root;
        this.DriveIsEnabled = true
        //this.page.DriveSelection.IsEnabled = true
    }
too
  • 3,009
  • 4
  • 37
  • 51
  • `UpdatePathManager` is called in by the `DriveSelection_SelectionChanged` it is included in my code snippet – szpic Aug 28 '14 at 11:28
  • Regardless when it is called, your binding does not check for this.driveSelection being null which means you need to ensure that it is set before binding is triggered and to do this just create DriveInfo instance in the constructor and possibly implement INotifyPropertyChange on it if you plan to change it's properties while it's data bound. – too Aug 28 '14 at 11:36
  • I updated my question with some new informations – szpic Aug 28 '14 at 11:36