CodeCannibal
CodeCannibal

Reputation: 344

WPF Dictionary Binding by key does not work

I really don't get it.

I created a viewmodel-class, which contains two objects, like this one:

public class MyViewModel{

public MyFirstObject FirstObject {get;set;}
public MySecondObject SecondObject {get;set;}

...
// Constructors and so on...
}

The FirstObject looks like this:

public class MyFirstObject {

    public int Id {get;set;}
    ...
    // Constructors and so on...
    }

}

And MySecondObject contains a Dictionary:

    public class MySecondObject{

            public Dictionary<int, string> MyDict {get;set;}
            ...
            // Constructors and so on...
            }
}

What I want to do now, is to get the dictionarys value for a key, which is a refence to MyFirstObject.Id - like this:

mySecondObject.myDict[myFirstObject.Id]

Doing this in C# is easy, but now I want to do this in xaml. I created a UserControl and set the DataContext to a MyViewModel-reference.

After that, I tried this:

<TextBox Text={Binding SecondObject[FirstObject.Id]} ../>

Unfortunately this is not working, because the key 'FirstObject.Id' can not be found.

Has anyone an idea how to fix that?

Thanks a lot! CodeCannibal

Upvotes: 0

Views: 525

Answers (1)

nemesv
nemesv

Reputation: 139798

Don't do this in XAML. Just create a new property on your viewmodel which encapsulates this logic.

You can also delegate the PropertyChangedEvent to propagate your value changes:

public class MyViewModel : INotifyPropertyChanged {

    private MyFirstObject firstObject;
    public MyFirstObject FirstObject
    {
        get { return firstObject; }
        set { firstObject = value; PropertyChanged("MyDictValue"); }
    }

    private MySecondObject secondObject;
    public MySecondObject SecondObject
    {
        get { return secondObject; }
        set
        {
            secondObject = value; PropertyChanged("MyDictValue");
            // you can subscribe here also for your MyDict changes if it is an
            // observable and you can call PropertyChanged("MyDictValue"); 
            // in the change event etc
        }
    }

    public string MyDictValue 
    { 
        get { return SecondObject.MyDict[FirstObject.Id]; } 
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

And bind to your new property:

<TextBox Text={Binding MyDictValue} ../>

With this approach you will have a place inside the MyDictValue to add additional logic like handling if FirstObject or SecondObject is null etc.

Upvotes: 1

Related Questions