简体   繁体   中英

Checking parent properties for null before binding

I am currently trying to find a way to check if a parent property is null before binding to a sub property, like this:

...{Binding Item.Text}

Is there a way to check if Item is null before accessing the Text property? As it stands right now I get a NullReferenceException in PresentationFramework.dll which crashes the app.

This is particularly strange as I set the Item in the ViewModel constructor and have verified that it exists before the rendering step begins:

public MyViewModel()
{
    Item = new Foo();
    Item.Text = "Bar";
}

I would suggest creating a viewmodel property for the model property you want to expose.

Since the example you've shown works for me..

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = new MyViewModel();
    }
}

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private Foo item;

    public MyViewModel()
    {
        Item = new Foo();
        Item.Item = "Bar";
    }

    public Foo Item
    {
        get
        {
            return this.item;
        }
        set
        {
            this.item = value;
            RaisePropertyChanged("Item");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class Foo
{
    public string Item { get; set; }
}

<TextBox Width="200" Height="30" Text="{Binding Item.Item, Mode=TwoWay}" TextAlignment="Center"/>

You can expose the subproperty and perform the checking like this..

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private Foo item;

    public MyViewModel()
    {
        //Item = new Foo();
        //Item.Item = "Bar";
    }

    public Foo Item
    {
        get
        {
            return this.item;
        }
        set
        {
            this.item = value;
            RaisePropertyChanged("Item");
        }
    }

    public string Bar
    {
        get
        {
            if(Item == null)
            {
                return "Item is null. OMG!";
            }
            else
            {
                return Item.Item;
            }
        }
        set
        {
            Item.Item = value;
            RaisePropertyChanged("Bar");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

<TextBox Width="200" Height="30" Text="{Binding Bar}" TextAlignment="Center"/>

With this, you might want to change your view model design.

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